Okay, I am receiving scores and names from a text file to calculate averages.
1 line contains a name, the next line will contain 3 scores separated by spaces.
Looks like this:

Tom Babidal
93 94 99
Billy Marks
13 98 56
etc
etc

My code seems to read the first 2 lines perfectly, then the other names are blank and numbers huge, so not correct at all.

Here's the code:

#include <iostream>
#include <string>
#include <cmath>
#include <iomanip>
#include <fstream>
using namespace std;

int main()
{

	infile.open ("studentscores.txt"); 

	getline(infile, student1); 
	infile >> score1 >> score2 >> score3; 
	
	getline(infile, student2);
	infile >> score4 >> score5 >> score6;
	
	getline(infile, student3);
	infile >> score7 >> score8 >> score9;

	infile.close();

The output of the 6 scores is:
93
94
98
2355420
1682270674
2752512
0
29729
2355440

It has the first name outputted correctly but when outputting the second and third its just empty.

Recommended Answers

All 7 Replies

You aren't reading the NewLine after the numbers. When reading numbers, the system stops reading when the number is finished.

You aren't reading the NewLine after the numbers. When reading numbers, the system stops reading when the number is finished.

Well I'm assuming (from some knowledge of vb) that I should be running a loop, but I am not allowed, so I am still stuck.

I don't know what that means in relation to my comment.

To expand on WaltP's post, the problem is likely due to the different behaviors of the input methods getline() and the >> operator.

Input in C++ is buffered, which means when you hit the enter key to stop input into the program as desired, the input goes to a buffer (think array or queue or whatever) where it waits for the next input method to extract the information and place the information into the designated variable. getline() removes the terminating char from the input buffer (in this case you are using the default new line char as the terminating char for getline()), but the >> operator does not.

Therefore, after the call to >> to read in score3 the terminating newline char remains in the input buffer and remains there when the next name is entered. The call to getline() to get the name for student2 then reads the input buffer, but the first thing it sees is the new line char left there by the call to >> to get score3. This new line char then terminates input into student2 immediately, without actually putting anything in student2 so when you try to output the result later, it is junk, or it's plain outright blank, like it's been skipped completely. The call to getline() removes the leading newline char in the input buffer, but leaves the name for student2 in the input buffer, so when the call to infile >> score4 happens, you are trying to put a string into a variable of type int, which will be junk, too. The call to >> score4 stops at the space between the first and last name of student2 so the call >> score5 results in junk again, etc.

To resolve this problem, either don't mix input methods in the same program, or clear the input buffer appropriately between calls to different input methods using the clear() method of the appropriate stream class. Basically, that usually means clearing the input buffer completely before each call to getline() if you are using >> in the program, too, although often, clearing just the first char in the input buffer will due. You can look up the syntax for clear() in your reference material if you decide to go that route. However, many people will never accept input accept as a string (using only getline() or >>, but not both) and then convert the input string to the appropriate type and store in the desired variable after appropriate validation of the input.

Excuse me, you would use the ignore() method of the stream class, not the clear() method as I erroneously indicted previously, to (remove and) ignore input from the input buffer. ignore() defaults to size 1, meaning ignore the one item that's been in the buffer the longest, but you can have it ignore up to the maximum size of a buffer in C++ or any arbritrary number of char between those two. I apologize for my earlier mistatement.

Yeah I had no idea what Walt was talking about, but when I went to my class she explained that I shouldnt put getline and infile >> together, which looks to similar to what your saying, thanks for explaining it, seeing as how I had no idea what to do from his response.

OK, here's a complete description:

File contains:

Tom Babidal<\n>
93 94 99<\n>
Billy Marks<\n>
13 98 56<\n>
etc<\n>
etc<\n>

your Code:

getline(infile, student1); 
	infile >> score1 >> score2 >> score3;

Execute getline() -- file now contains:

93 94 99<\n>
Billy Marks<\n>
13 98 56<\n>
etc<\n>
etc<\n>

Execute infile -- file now contains:

<\n>
Billy Marks<\n>
13 98 56<\n>
etc<\n>
etc<\n>

Note that I said "You aren't reading the NewLine after the numbers. When reading numbers, the system stops reading when the number is finished." Well, there it is -- line 1.
Execute getline() once more, reads to the next NewLine -- file now contains:

Billy Marks<\n>
13 98 56<\n>
etc<\n>
etc<\n>

What's the infile going to read?

Maybe you could have asked a question rather than making a cryptic comment...

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.