0

Hello I have a question about looping and reading files using fstream. I have this code and the problem is I can't get it to loop.

int studentSize, mark1,mark2,mark3; 
string programme, course1, course2, course3;
filein >> studentSize;
filein >> programme;
filein.ignore();

while(getline(filein, name, '\n') &&
      filein >> id &&
      filein >> ws && 
      getline(filein, course1, '\n') &&
      filein >> mark1 &&
      filein >> ws &&
      getline(filein, course2, '\n') &&
      filein >> mark2 &&
      filein >> ws &&
      getline(filein, course3, '\n') &&
      filein >> mark3 &&
      filein >> ws)
{
    if( programme == "Physics" )
    {
        for(int i=0; i < studentSize; i++)
        {
            phys.push_back(new physics());
            phys[i]->setNameId(name, id);
            phys[i]->addCourse(course1, mark1);
            phys[i]->addCourse(course2, mark2);
            phys[i]->addCourse(course3, mark3);
            sRecord[id] = phys[i];
        }
    }
}

I tried to add a while loop before the code. And do something like this:

filein >> studentSize;
filein >> programme;
filein >> repeat;
filein.ignore();
while(repeat == '&')
  { //above code }

and make my file like this so that it loops when fstream >> detects the & character but it doesn't work. I have no idea why.

2
Mathematics
&
Ashley    
7961000
Doto
99
C++
99
Meh
99
&
Dwayne
7961222
Quantum
99
heh*
99
Computing
99
Cubed
  • 35
  • 2
  • 7
  • Well, what happens when you step through it in your IDE's debugger? – Cameron Apr 30 '14 at 19:29
  • It can be compiled but then it goes into an infinite loop. – Cubed Apr 30 '14 at 19:39
  • Drop these stupid `filein.ignore()` –  Apr 30 '14 at 19:40
  • 1
    I'd suapect the `filein.ignore()` statement being cause of your troubles ... – πάντα ῥεῖ Apr 30 '14 at 19:41
  • If you want to consume whitespaces, you can use `filein >> std::ws`. – dyp Apr 30 '14 at 19:41
  • 1
    Also `for(int i=0; i < studentSize; i++)` is likely wrong –  Apr 30 '14 at 19:44
  • It still doesnt work after dropping filein.ignore() . Still goes to infinite loop. – Cubed Apr 30 '14 at 19:44
  • You're overwriting `mark` btw. – dyp Apr 30 '14 at 19:45
  • It's still not clear what you're trying to do here. Could you explain the parsing requirements for your file? – David G Apr 30 '14 at 19:48
  • Your data is ill-formed. A `*` is missing after the second name `Dwayne`. (I'm not sure why you use a `*` as a delimiter, why not just use the `\n`?) – dyp Apr 30 '14 at 19:52
  • Your data is ill-formed part 2: There needs to be an additional character after the final `99`, otherwise the final `ignore` in the looping condition will fail (EOF). Arguably, that's a problem of how you read the data and not of your data sample. – dyp Apr 30 '14 at 19:54
  • do you ever change `repeat` after the initial `filein >> repeat;`? Otherwise, I don't see why you'd expect that loop to ever end. – Red Alert Apr 30 '14 at 19:56
  • also if you want to consume whitespace, use `filein >> std::ws`, not `filein.ignore()`. Is that why you are using so many `ignore()`s? – Red Alert Apr 30 '14 at 19:59
  • Okay I fixed the things about `ignore()` and ill-formed data (except the part 2 (I kinda dont udnerstand)). But the problem still persists, the loop still goes infinite. @RedAlert What do you mean by that? – Cubed Apr 30 '14 at 20:09
  • 1
    your condition is `while(repeat == '&')`. You never change `repeat`. How can that loop end? – Red Alert Apr 30 '14 at 20:17
  • You need to consume the `&` properly. [Live example](http://coliru.stacked-crooked.com/a/d7b1149c9eb78202) – dyp Apr 30 '14 at 20:24
  • @dyp Worked properly. But now I have another problem. The 1st student's data is overwritten by the 2nd student's data. Any solution to this? – Cubed Apr 30 '14 at 20:33
  • I could write that program for you step by step, but that would cost me a lot of time and won't help you much. Reading an [introductory book on C++](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) will probably help you more, better and faster, even though you'll need some time to get started. – dyp Apr 30 '14 at 20:37

1 Answers1

0

Using ignore() is a poor way to consume a &. This is a working parse of your sample input:

int studentSize, id, mark1,mark2,mark3;
string name, programme, course1, course2, course3;
char delim;

cin >> studentSize >> programme >> delim;
cout << studentSize << ", " << programme << ", " << delim << endl;
while(cin >> name >> id >> course1 >> mark1 >> course2 >> mark2 >> course3 >> mark3)
{
    //do more stuff with your variables here
    cout << name << ", " << id << ", " << mark1 << ", " << course1 << ", " << mark2 << ", " << course2 << ", " << mark3 << ", " << course3 << < endl;
    cin >> ws >> delim; //consume the &
}

Live Demo

Red Alert
  • 3,786
  • 2
  • 17
  • 24
  • `cin >> name` is different from `getline(cin, name)`: The latter can read names with spaces. – dyp Apr 30 '14 at 21:08