tags:

views:

70

answers:

3

Hello,

I am a beginner at C++ and I'm trying to use the getline() function for the first time. When I wrote this code, 2 errors showed up.

What is this code supposed to do? It is supposed to read 4 numbers from read.txt then calculate it to find the mean and write the output in output.txt.

The 4 numbers (in read.txt) are all on separate lines like this:

6
12
15
19

Here is the code:

#include <iostream>
#include <fstream>
#include <string>
using namespace std;

    int main () 
    {
     ifstream readFile;
        ofstream sendFile;
     readFile.open ("read.txt");
     sendFile.open ("output.txt");;

     float mean;
     int num, num2, num3, num4;
     getline(readFile, num), getline(readFile, num2), getline(readFile, num3), getline(readFile, num4); 

     readFile >> num >> num2 >> num3 >> num4;
     sendFile << "1. The mean of " << num << ", " << num2 << ", " << num3 << ", and " << num4 << "is " << (num + num2 + num3 + num4) / 4;

     readFile.close();
     sendFile.close();

      system ("PAUSE") ;
      return 0;
    }

Here are the errors: IntelliSense: no instance of overloaded function "getline" matches the argument list 20 IntelliSense: too few arguments in function call 20

+1  A: 

std::getline() takes two arguments: a stream and the std::string object into which to read the next line (and an optional third argument, the delimiter). You are passing an int instead of a std::string.

You should probably use the ordinary formatted extraction:

if (readFile >> num >> num2 >> num3 >> num4) {
    // extraction succeeded!
}
else {
    // extraction failed; handle the error here
}
James McNellis
Okay now I know getline() only takes strings, thanks!
Evan
Note that if there is a an error reading the 2nd, 3rd or 4th numbers, there will be no way to tell, as the expression will fail the same way for each case. I suggest reading each number separately and testing for failure.
Thomas Matthews
@Thomas: It depends on the fidelity of error handling that is needed. Quite often it is sufficient to use all-or-nothing error handling, especially with input operations.
James McNellis
A: 

getline reads into std::string, it can't read into ints. Just use readFile >> num >> num2 >> num3 >> num4; as you already have, and delete the line with getlines.

On another note, you don't need to close the files explicitly here as the destructors of file stream objects will take care of that for you.

usta
Oh okay, thanks a lot! It actually works now.
Evan
A: 

std::getline is a useful tool for reading a single line of text or reading text up to a specific character, and writing it to a std::string where it can then be read further. By default it uses newline i.e. '\n' as the delimiter but you can change this.

With regards to using a stream to read in a number of integers then output their mean, why not just read to the end of the file, thus:

int count = 0, total = 0, num;
while( instr >> num )
{
  ++count;
  total += num;
}

float mean = (count > 0 ) ? total / num : std::numeric_limits<float>::quiet_NaN();
outstr << mean;

You could make that a function, taking istream & instr and ostream & outstr

Suppose now we want to change that to read multiple lines, each with numbers delimited by space or tab. In our output we write all the means on their own line.

Now do something like this:

std::string line;
while( std::getline( bigInStr, line ) )
{
   std::istringstream iss(line);
   outputMean( iss, outstr );
   outstr << '\n';
}

although you might want to not actually output the NaN but just leave that line blank in the output. A function calculating the mean probably would want to use a NaN as a return value if it has to return a float. We could calculate the variance, skewness and kurtosis at the same time if we want whilst iterating.

Then you would output these as multiple values on the line and you would have to pick your own delimiter. My own preference is to use tab ('\t') in this situation.

_

CashCow
Should be `quiet_NaN` instead of `quiet-NaN`.
usta
yeah typo, on a UK keyboard at least they are on the same key with _ requiring a shift. If you have a function to calculate the mean then with 0 entries you probably would want to return some kind of NaN but if you are printing you probably want to leave that line blank.
CashCow