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?

johwiltb
  • 123
  • 1
  • 2
  • 10
  • 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); }`. – Joseph Mansfield Apr 28 '13 at 15:13
  • 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. – Potatoswatter Apr 28 '13 at 15:50
  • @Potatoswatter 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. – James Kanze Apr 28 '13 at 16:06

2 Answers2

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.

Andy Prowl
  • 124,023
  • 23
  • 387
  • 451
  • Doesn't make sense. The declaration should be in `` 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. – Potatoswatter Apr 28 '13 at 15:48
  • @Potatoswatter: I tried not `#include`ing `` and that is exactly the error I get. – Andy Prowl Apr 28 '13 at 15:49
  • 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. – Potatoswatter Apr 28 '13 at 15:52
  • @Potatoswatter Without including ``, the compiler may not even know that there is a class `ifstream`. But the correct solution is _not_ to include ``; it is to use `istream` as the argument, not `ifstream`. – James Kanze Apr 28 '13 at 16:04
  • @Andy Prowl I have the #include and , so is there another possibility? – johwiltb Apr 28 '13 at 16:57
  • @johwiltb: Are you extra sure? I can't think of another possibility for *that* error. – Andy Prowl Apr 28 '13 at 17:02
  • @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 ' to the implementation file does make it work well – johwiltb Apr 28 '13 at 18:02
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.

Potatoswatter
  • 134,909
  • 25
  • 265
  • 421
James Kanze
  • 150,581
  • 18
  • 184
  • 329
  • 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. – johwiltb Apr 28 '13 at 16:59
  • @johwiltb 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. – James Kanze Apr 28 '13 at 17:17