File Read Not Completing, WHY?

I am having trouble using a struct to complete the reading of a file. I have used struct before in a similar fashion and had zero issues reading the file. This time though I am running into an issue where I cannot seem to get the name and the double values separated and stored correctly for each of the objects (rivals[7]). Can someone elaborate as to what is going on or help with why this is happenning? I am thinking it is the for loop, as messing with it has produced different results; though, I have used the same sort of for loop before and did not have this issue, as it is only reading one line instead of the whole file. Someone please, explain this mess so far.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
using namespace std;

int numNum=0;
const int peo=7;

struct comps 
{
string name;
double scores[10];
}rivals[7];

int main ()
{
	
	ifstream read;
	string file=("scores.txt");
	read.open(file.c_str());
	int x;

	for(x=0; x<100; x++)
	{
	read>>numNum;
	if (numNum>0)
	{
	cout<<numNum;
	break;
	}
	}
	cout<<endl;
	
	for (x=0; x<peo; x++)
		read>>rivals[x].name>>rivals[x].scores[x];
	
	for(x=0; x<peo; x++)
		cout<<rivals[x].name<<" "<<rivals[x].scores[x];
	cout<< endl;
	system("pause");
	return 0;
}
//Use the info below as the text file

7
Anne 2.0 8.5 8.5 9.0 9.0 9.0 9.5 8.5 8.0 9.5
Sarah 1.6 7.5 8.5 8.0 8.0 7.0 9.0 8.5 8.5 8.0
Deborah 2.3 9.0 9.0 9.5 10.0 10.0 9.5 9.5 9.5 9.5 
Kathryn 2.4 9.0 9.0 9.0 9.5 9.5 9.5 9.0 8.0 8.5
Martha 2.7 9.0 9.0 9.5 9.5 9.0 8.5 8.5 8.5 9.5
Elizabeth 2.9 8.0 8.0 7.5 8.5 8.5 8.0 8.0 7.5 8.5
Tina 2.5 8.5 8.5 8.5 8.5 8.5 8.5 8.5 8.5 8.5
Last edited on
At line 26 read>>numNum; the program attempts to read an integer from the file. Instead the file contains the string "Anne". Thus the input fails and the read.fail() flag is set. All further file access will fail after that.

Are you sure that this is the correct data file? It doesn't seem to start out with 100 consecutive integer values, which is what the program is expecting to find. Or perhaps you need to re-think the program logic to match the actual data.
I am sure the text file is right. This issue really has me stumped. It is not line 26. Even if you remove line 26 and the if loop as well along with the number 7 from the text file, this one line only of file stream being read occurs. I am done looking at it for tonight. Tomorrow, I will try using a vector instead and see if I can pushback everything instead.
Last edited on
Well, look at this code:
35
36
    for (x=0; x<peo; x++)
        read>>rivals[x].name>>rivals[x].scores[x];

the above attempts to read a single name, followed by a single score. But the file contains more than one score following each name. I think you need some sort of nested loop here, where the two subscripts here are controlled separately: rivals[x].scores[x] instead of x and x, use say x and y.

Using a vector and push_back() would probably be a safer solution, as it would not depend upon the assumption that the input file contains a specific number of lines.
Last edited on
So after messing with it yesterday, nesting another for loop produces the names only. Here it is, and the logic doesn't make any sense.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
using namespace std;

int numNum=0;
const int peo=7;

struct comps 
{
string name;
double scores[10];
}rivals[peo];

int main ()
{
	
	ifstream read;
	string file=("scores.txt");
	read.open(file.c_str());
	int x;
	int y;
	for(x=0; x<100; x++)
	{
	read>>numNum;
	if (numNum>0)
	{
	cout<<numNum;
	for(x=0; x!=numNum; x++)
	{
		read>>rivals[x].name;
		for (y=0; y<10; y++)
		{
			read>>rivals[x].scores[y];
		}
	} 
	break;
	}
	}
	cout<<endl;
	
	for(x=0; x!=numNum; x++)
		cout<<rivals[x].name<<" "<<endl;
	
	cout<<endl;
	system("pause");
	return 0;
}
Last edited on
A trip down memory lane with some old parsing tactics; lo and behold. Still I am not happy with this code, I would of much rather used a struct to save each person as an object with the array of scores. I will continue to try and figure it out. The logic is the issue, I just cannot figure out how to write it correctly with the for loops. Any extra help is appreciated as always.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int numNum=0;

int main ()
{
	
	ifstream read;
	string file=("scores.txt");
	read.open(file.c_str());
	string name;
	double scores[10];
	char space=' ';
	int x;
	int y;
	
	for(x=0; x<100; x++)
	{
	read>>numNum;
	if (numNum>0)
	{
	cout<<numNum<<endl;

  while (!read.eof())
  {
	 
	  read>>name;
	  cout<<'\n'<<name;
	  for(x=0; x<10; x++)
	  {
	  read>>scores[x];
	  cout<<" "<<scores[x]<<" ";
	  }
	  
	  read.get(space);
	  
  } 

	break;
	}
	}
	cout<<endl;
	system("pause");
	return 0;
}

//text file to be read

7
Anne 2.0 8.5 8.5 9.0 9.0 9.0 9.5 8.5 8.0 9.5
Sarah 1.6 7.5 8.5 8.0 8.0 7.0 9.0 8.5 8.5 8.0
Deborah 2.3 9.0 9.0 9.5 10.0 10.0 9.5 9.5 9.5 9.5
Kathryn 2.4 9.0 9.0 9.0 9.5 9.5 9.5 9.0 8.0 8.5
Martha 2.7 9.0 9.0 9.5 9.5 9.0 8.5 8.5 8.5 9.5
Elizabeth 2.9 8.0 8.0 7.5 8.5 8.5 8.0 8.0 7.5 8.5
Tina 2.5 8.5 8.5 8.5 8.5 8.5 8.5 8.5 8.5 8.5
Last edited on
I'm trying to be careful not to simply paste my own solution to this. But a couple of comments.
At line 27, while (!read.eof()) it is really not a good idea to test for eof in a while loop like this. Typically instead you would have something like
while (read>>name) or perhaps while (getline(read, line))

I still have no idea what the code at line2 20 to 25 is supposed to achieve:
1
2
3
4
5
6
	for(x=0; x<100; x++)
	{
	read>>numNum;
	if (numNum>0)
	{
	cout<<numNum<<endl; 


Which piece of data from the file is supposed to be read into the variable numNum, and why? And what is the purpose of the variable x here?

Sorry if i'm not being much help, I'm just trying to make sense of what you are doing.
I am working on becoming better at programming. I have these assignments that I want to learn how to program, and each one I am writing from scratch. I guess taking a few weeks off from working on this skill really shows though. I have already worked with arrays before, (2-D, dynamic vectors etc.), but for some reason when reading from a text file things get a bit more unruly with the logic, or at least that is what I am experiencing so far.

This assignment wants the file to be read, and then the scores to be sorted for each contestant. After the scores are sorted, the lowest and highest scores are to be dropped for each contestant and then multiplied by the first number of the array (or the difficulty rating) to achieve a total of the contestants score. At the end of the output, the winner of the competition should also be displayed with the total score.

Seems simple enough at first look, then a few hours after working on it I realize how much I still need to work on programming.

As for the numNum variable, or the number at the very first line of the file: it is to be used as a sentinel for loop control (it represents the number of contestants).

Sorry the long-winded response.

Last edited on
Ah, thanks for the clarification, I'd missed the number 7 on the first line of the file previously. Here I think you might have something like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
int main()
{
    ifstream fin("scores.txt");
    int numStudents;
    
    fin >> numStudents;
    if (!fin)
    {
        cout << "error reading number of students" << endl;
        return 1;
    }
    
    string name;
    double score[10];
    
    for (int i=0; i<numStudents; i++) 
    {
        fin >> name;
        for (int j=0; j<10; j++)
            fin >> score[j];
            
        if (!fin)
        {
            cout << "error reading student number " << i+1 << endl;
            return 1;
        }
    
        // do something with the data for this student
    }

    return 0;
}  


Above, note the error-checking after reading from the file. Overall, I think your earlier code with a struct to hold the data for one person was a good idea, and you could use either an array or vector to hold all of the data.

There are lots of ways to structure the code. That is just one example. Another way might be to use getline() to read each line into a string, then a stringstream to extract the details.
Topic archived. No new replies allowed.