Reputation: 7181
If I open a new file for input, and I call input >> listSize;
outside of a while loop and then continue calling input >> anothervariable
will it automatically progress through the file or will it read the first line again?
Example:
input >> listSize;
BaseStudent* studentlist = new BaseStudent[listSize.atoi()];
while (!input.eof())
{
input >> anothervariable; // I want this to start on the second line, not the first
}
The input file looks like this and we can code to the pattern (ignore the extra blank lines):
12
Bunny, Bugs
Math 90 86 80 95 100 99 96 93
Schmuckatelli, Joe
History 88 75 90
Dipwart, Marvin
English 95 76 72 88
Crack Corn, Jimmy
Math 44 58 23 76 50 59 77 68
Kirk, James T.
English 40 100 68 88
Lewinsky, Monica
History 60 72 78
Nixon, Richard
English 35 99 70 70
Lincoln, Abraham
History 59 71 75
Clinton, William
Math 43 55 25 76 50 58 65
Duck, Donald
English 34 100 65 65
Duck, Daffy
History 55 70 70
Bush, George
Math 44 54 29 75 50 55 60
Upvotes: 1
Views: 1043
Reputation: 490623
Others have already pointed out that the answer to your question is "yes", so I won't worry about that part.
As for the rest, I think I'd write it a bit differently. Your file obviously represents structured data, and I'd write the code to reflect that fact reasonably directly. I'd start by defining a structure reflecting the data in the file:
struct test_scores { // maybe not tests. Change if appropriate
std::string student;
std::string course;
std::vector<int>
};
Then, I'd write a function to read one of those items from the file:
std::istream &operator>>(std::istream &is, test_scores &ts) {
// for the moment assuming there are no blank lines in the file.
std::getline(is, ts.student);
std::string temp;
std::istringstream buffer(temp);
buffer >> ts.course;
int score;
while (buffer>>score)
ts.scores.push_back(score);
return is;
}
In C++, however, it's really easier to just read whatever amount of data is there, than to prefix the data with the count. Given that count is present, the easiest thing to do is probably to just read and ignore it:
std::string ignore;
std::getline(infile, ignore);
Then we can read the real data pretty easily:
std::vector<test_scores> student_scores;
test_scores tmp;
while (infile >> tmp)
student_scores.push_back(tmp);
...or, we can use C++'s handy-dandy istream_iterator
s to simplify the code even more:
std::vector<test_scores> student_scores((std::istream_iterator<test_scores>(infile)),
std::istream_iterator<test_scores>());
That's it -- it defines the vector and initializes it from the input file, all in one (fairly) simple operation.
Upvotes: 2
Reputation: 264669
When you read from a stream the data is used.
Next time will read from the last point read "up-to"
Though stream operator >> will skip proceeding white space but will not read the white space after the object (which can be a pain if your input is line orientated, as you don't see new lines easily).
The best way to get around this is to explicitly read lines at a time then parse the line:
std::string line;
std::getline(input, line); // Read a line
// Now look what is in the line.
std::stringstream linestream(line);
linestream >> dataItem1 >> dataItem2 >> dataItem3; /// etc.
Also note:
// This is not good. If there are any errors in your file it will loop forever.
while (!input.eof())
It is normal to loop over the input using:
while(input >> data)
{
// If you get in here then the read worked.
}
// You will fall out of the loop when
// 1) EOF
// 2) There is an error.
So if we combine both techniques:
std::string line1; // Name,
std::string line2; // Scores
std::string empty; // Empty line in data file.
while(std::getline(input, line1) && std::getline(line, empty) && std::getline(input, line2))
{
// line1 => Bunny, Bugs
// empty =>
// line2 => Math 90 86 80 95 100 99 96 93
// Enter the loop only if we get a name and a score line
std::getline(line, empty); // Optionally read a trailing line (there may not be a last one);
// dataStream => Math 90 86 80 95 100 99 96 93
std::stringstream dataStream(line2);
std::string subject;
int score;
dataStream >> subject; // subject => Math
while(dataStream >> score)
{
// We read another score from the data line;
// score is 90 first time 86 second time etc.
}
}
Upvotes: 3
Reputation: 13189
Thew file pointer is always advanced past what you have already read.
Upvotes: 0