Getline issue with input of open file stream
Asked Answered
I

2

1

I'm trying to figure out why this is broke now, because I had it working and I'm not sure what is wrong. I'm trying a simple getline from a file that's been opened, however, the compiler keeps giving me errors. I've tried finding someone else with these issues, but I haven't been able to find anyone else with this. Any advice?

void Foo::bar(ifstream &inputFile)
{
// Read in the data, parse it out, and 
// call loadQueue
string input;
do {    
    getline(inputFile, input);
    loadQueue(input);
}while (!(inputFile.eof()));

}

Here is what I get in return:

g++    -c -o Airworthy.o Airworthy.cpp
Foo.cpp: In member function ‘void Airworthy::readData(std::ifstream&)’:
Foo.cpp:25:27: error: no matching function for call to ‘getline(std::ifstream&, std::string&)’
Foo.cpp:25:27: note: candidates are:
In file included from /usr/lib/gcc/x86_64-unknown-linux-gnu/4.7.2/../../../../include/c++/4.7.2/string:55:0,
             from /usr/lib/gcc/x86_64-unknown-linux-gnu/4.7.2/../../../../include/c++/4.7.2/bits/locale_classes.h:42,
             from /usr/lib/gcc/x86_64-unknown-linux-gnu/4.7.2/../../../../include/c++/4.7.2/bits/ios_base.h:43,
             from /usr/lib/gcc/x86_64-unknown-linux-gnu/4.7.2/../../../../include/c++/4.7.2/ios:43,
             from /usr/lib/gcc/x86_64-unknown-linux-gnu/4.7.2/../../../../include/c++/4.7.2/ostream:40,
             from /usr/lib/gcc/x86_64-unknown-linux-gnu/4.7.2/../../../../include/c++/4.7.2/iostream:40,

Any ideas on what the issue is?

Intuitional answered 28/4, 2013 at 15:3 Comment(3)
In addition to what Andy said, you're likely to loadQueue being called for the last line of your file twice. Change your loop to while (getline(inputFile, input)) { loadQueue(input); }.Tremann
Please show us the entire error message. And to elaborate on sftrabbit, eof() doesn't return true when there's no more input, it only returns true after an input operation has already failed due to eof.Franchot
@Franchot Or not. The problem is that until input has failed, eof() may or may not return true. After having read the last line (or the last input, whatever it is), eof() may return either true or false; you can't really be sure which.Messer
S
6

Most likely you forgot to #include all the necessary standard headers. One possibility is:

#include <fstream>

Or perhaps you forgot to:

#include <string> 

You always have to #include all pertinent standard headers explicitly, without relying on indirect inclusion through some other headers.

Sartorial answered 28/4, 2013 at 15:5 Comment(7)
Doesn't make sense. The declaration should be in <string> and that is already mentioned in the part of the diagnostic message he's shown us. You can't get std::string without getting the appropriate getline overload.Franchot
@Potatoswatter: I tried not #includeing <fstream> and that is exactly the error I get.Sartorial
Ahh, because it doesn't know ifstream is derived from istream. Alright, +1. But another fix would be to take an istream & parameter. Usually fstream parameters are a mistake.Franchot
@Franchot Without including <fstream>, the compiler may not even know that there is a class ifstream. But the correct solution is not to include <fstream>; it is to use istream as the argument, not ifstream.Messer
@Andy Prowl I have the #include <fstream> and <string>, so is there another possibility?Intuitional
@johwiltb: Are you extra sure? I can't think of another possibility for that error.Sartorial
@AndyProwl ahh I'm sorry. I had it added to the header file, but not to implementation file. I think it's more an issue with the Makefile, which is a whole other question itself, but adding '#include <fstream>' to the implementation file does make it work wellIntuitional
M
1

As Andy says, you need the appropriate includes. There are, however, at least two other major problems with your code (one of which will affect which includes you need):

  • You should never (or almost never) pass ifstream as an argument to a function. Unless the function is going to do an open or a close, you should pass it std::istream&, so that it can be called with any istream, and not just ifstream.

    Once you've changed this, you need to include <istream>, and not <fstream>. (<fstream> includes <istream>. And a lot more which you don't need.)

  • You should never loop on ! inputFile.eof(). It doesn't work. In your case, the loop should be

    while ( std::getline( inputFile, input ) ) {4
        //  ...
    }
    

    It works, and almost nothing else does.

    In general, a do...while loop is almost always wrong when doing input; it results in your processing the input even when it fails (which you do—any use of input after the getline but before testing whether the getline has succeeded is an error). And the results of inputFile.eof() are not really well defined until input has failed. Using istream::eof() to control a loop is almost always an error.

Messer answered 28/4, 2013 at 16:2 Comment(2)
The function is called through the main application after the file is opened. Following the function call, the file is then close. But I will definitely work out the loop issue. I appreciate the advice on that.Intuitional
@Intuitional Regardless of when the function is called, if a function doesn't use any of the interface which is strictly ifstream, like open and close, then it should take an istream&, not an ifstream&. In practice, it's very common for an application to start with an ifstream, only to switch to some custom, in house stream later; you don't want to have to find every function which reads from the stream, and change them.Messer

© 2022 - 2024 — McMap. All rights reserved.