0
int main(int argc, char** argv) 
{
    ifstream input;
    ofstream output;
    input.open("input.txt");
    output.open("output.txt");

    char c;

    output << "ID\tLName\tFName\tQ1 Q2 Q3 Q4 Q5 Q6 T1 T2 Final" << endl;
    output << "------------------------------------------------------" << endl;

    //Loop through each line until there is none left.
    string s;
    while (getline(input, s)) 
    {
        output << readNext(input) << "\t"; //ID
        output << readNext(input) << "\t"; //FName
        output << readNext(input) << "\t"; //LName

        output << endl;
    }
    return 0;
}

string readNext(ifstream& input) 
{
    string s;
    char c;

    if (input.peek() == ',') input.get(c);

    do {
        input.get(c);
        s += c;
    } while(input.peek() != ',');

    return s;
}

The line "while (getline(input, s))" gets me stuck in an infinite loop. Could anyone explain why? I've been told by numerous people that this is the correct way to read input rather than looking for an EOF.

Sample Input

11111,Lu,Youmin,10,9,8,10,8,9,95,99,100 
22222,Lu,Eddie,7,8,9,10,10,10,100,92,94
WhozCraig
  • 65,258
  • 11
  • 75
  • 141
user1884814
  • 31
  • 1
  • 1
  • 6
  • You can open a stream directly as in `ifstream input("input.txt");`. Also, it might be wise to check if the file was *actually* opened. – Bartek Banachewicz Feb 06 '13 at 01:40
  • I don't think that's the issue though, you do know `std::getline` has a third parameter right? Why don't you put the third parameter as `','` to do what you're currently attempting on doing? – Rapptz Feb 06 '13 at 01:41
  • The third parameter is optional according to http://www.cplusplus.com/reference/string/string/getline/. I'm not using a comma to delimit my lines, I'm using the comma to delimit sections in each line. – user1884814 Feb 06 '13 at 01:54
  • This is my input.txt: 11111,Lu,Youmin,10,9,8,10,8,9,95,99,100 22222,Lu,Eddie,7,8,9,10,10,10,100,92,94 By the way, how do I add newlines in my comment field on this site. When I press enter I just end up submitting. – user1884814 Feb 06 '13 at 01:56
  • You first apply `getline` (which reads a line from the input -- this line will be gone from the input!), and then you use `peek` and `get` to read from the same input source. What you should do instead is to apply `readNext` (or a rewritten version of it) to the string `s` that `getline` filled. – jogojapan Feb 06 '13 at 01:58
  • If anything jams you in a infinite loop in this code, it would be the do-while, in `readNext()`. A file ending without a comma (such as a blank line) will spin in that do-while forever, as once `input.good` is no longer lit, `peek()` just returns `Traits::eof()`, which is obviously **not** equal to `,`. Have you tried running this in a debugger and/or instrumenting it at all? – WhozCraig Feb 06 '13 at 01:58
  • If I made readNext read the string instead of the stream it wouldn't save its spot each time. I've ran the debugger again and it does get stuck in the do while, not the while. Last time I placed the breakpoint in a stupid spot. Everything in the program works absolutely perfectly except it just doesn't quit when it's finished. It does output everything it should into output.txt just fine. – user1884814 Feb 06 '13 at 02:08
  • What I don't get is why the while loop iterated another time at all to let the do while catch it in an infinite loop in the first place. – user1884814 Feb 06 '13 at 02:09
  • @user1884814 did you check your data file (that thing we've never seen)? As I said, if that thing ends on a blank line, you will send essentially nothing into your input scheme, which will loop forever. I would *strongly* advise you consider rethinking the input scheme strategy of this loop set. An input scheme should *never* consider the input gospel and introduce a possible infinite loop if that assumption turns on its ear. – WhozCraig Feb 06 '13 at 02:12
  • input.txt does not end with a blank line, I checked. It's just those two lines I posted a few comments above. This is my very first assignment for my c++ class that started a week ago so I have no idea how to do anything except what I've used above. What do you suggest for a different input strategy? – user1884814 Feb 06 '13 at 02:18
  • Well I've solved it by adding "if(input.eof()) break;" as the first line in the while loop, but I still don't very well understand what the problem was. – user1884814 Feb 06 '13 at 02:30
  • Sorry. was out for dinner. If I get a chance I'll try and post something for you. No promises, but I'll try. Glad you found something that works. – WhozCraig Feb 06 '13 at 02:38
  • @user1884814 ok. This is obviously different from your code, but the premise is the same. [This code sample](http://ideone.com/8kFGPd) reads *all* the values on the line, and drops them in separated by tabs. I leave the limiting to the first three values and then the handling of the remaining integer grades to you, but no infinite loops allowed. Note: the sample takes the input file and output file as command line parameters. If you specify neither, it uses cin/cout. If you specify one, it is used as input, and dumps to cout. Hope it helps. – WhozCraig Feb 06 '13 at 04:20
  • getline may be returning an istream (according to this link [http://www.cplusplus.com/reference/string/string/getline/]. Since the returned value is non-zero (not sure how a reference would be 0), the condition is true, so the loop will continue even if there is no input. I would try _getline(input, s).eof()_ and see if that will exit the while loop as eof() returns a bool to indicate of the eof bit is set. – Glenn Feb 06 '13 at 04:28

1 Answers1

0

Try this. The infinite loop is most probably because of a missing comma at the eof. Hence also check for the eof would be my suggestion.

string readNext(ifstream& input) { string s; char c;

    if (input.peek() == ',') input.get(c);

    do {
        input.get(c);
        s += c;
    } while(input.peek() != ',' && ! input.eof()); // Check for the end of file.

    return s;
}
Darzen
  • 1,105
  • 3
  • 13
  • 29