text file not displaying right

Pages: 12
I'm trying to display a text file with has a list of students with some details. There are 15 students but when i run the program only the last student shows up 15 times.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
fstream infile;
	 infile.open(name);
		while (!infile.eof()) 
		{
		infile >> aStudent.number >> aStudent.dob.day >> aStudent.dob.month >> aStudent.dob.year >> aStudent.scores[0] >> 
aStudent.scores[1] >> aStudent.scores[2] >> aStudent.scores[3] >> aStudent.scores[4] >> aStudent.scores[5];

cout << "Student Number\t" << "DOB\t\t" << "Student Scores" << endl; 
	for (int i = 0; i < 15; i++)
	{
	cout << aStudent.number << "\t\t" << aStudent.dob.day <<"/" <<aStudent.dob.month <<"/" << aStudent.dob.year <<"\t"<< 
aStudent.scores[0] << aStudent.scores[1] << aStudent.scores[2] << aStudent.scores[3]<< aStudent.scores[4] << aStudent.scores[5]<< endl;	   
          }
 infile.close();

The solution is probably really simple but i just can't spot the problem.
Thanks
Last edited on
Shouldn't you be increasing aStudent, so it'll point to the next student, in your while loop?
i thought the for loop was doing that
If I'm correct, your only repeating the loop 15 times, displaying the same aStudent because you, as whitenite1 said, don't apply any changes to the object.

The last student is displayed 15 times because the last student was saved in aStudent. You should find a way to increase aStudent or something.

Forgive me if I'm wrong, I'm quite new myself :o.
ok I understand but how would I increase aStudent each time? is it just aStudent ++ or something?
First thing that pops to mind is to assign each student to a different object, I think this can be obtained with an array. Although I'm not quite sure whether you can create arrays from classes, I think it's possible tho.

you'd get something like

infile >> aStudent[n].number >> aStudent[n].dob.day >> ...

Can someone with more knowledge correct me if I'm wrong?
ok thanks but now there is an error with [n] it says no operator "[]" matches these operands
You probably made a struct/class named Student. Then put Student aStudent; You need to instead make more than the one. Student aStudent[20];
Then, change original post to:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
fstream infile;
	 infile.open(name);
int n=0;
		while (!infile.eof()) 
		{
		infile >> aStudent[n].number >> aStudent[n].dob.day >> aStudent[n].dob.month >> aStudent[n].dob.year >> aStudent[n].scores[0] >> 
aStudent[n].scores[1] >> aStudent[n].scores[2] >> aStudent[n].scores[3] >> aStudent[n].scores[4] >> aStudent[n].scores[5];
             n++;
} // fill in all students
infile.close();
cout << "Student Number \t"  << " DOB\t\t" << "Student Scores" << endl; 
	for (int i = 0; i < 15; i++)
	{
	cout << aStudent[i].number << "\t\t" << aStudent[i].dob.day <<"/" <<aStudent[i].dob.month <<"/" << aStudent[i].dob.year <<"\t"<< 
aStudent[i].scores[0] << aStudent[i].scores[1] << aStudent[i].scores[2] << aStudent[i].scores[3]<< aStudent[i].scores[4] << aStudent[i].scores[5]<< endl;	   
          }  // prints out the students, scores, etc. 

Last edited on
no still not working heres the structs i made:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
typedef struct 
 {
	int day;
	int month;
	int year;
 } Date; 

typedef struct 
 {
	int number;
	Date dob;
	float scores[NUM_SCORES];
 } Student;

typedef Student ItemType;

struct ListType 
{
	int length;
	ItemType info [MAX_ITEMS];
};
can any help with this please? the solution is probably simple but i cant figure it out
thanks
I'll walk you through what's going on.

A
1
2
fstream infile;
infile.open(name);


You should already know this one.

B
1
2
while (!infile.eof()) 
{

As long as we haven't reached the end of the file, follow the inside of this loop

C
1
2
infile >> aStudent.number >> aStudent.dob.day >> aStudent.dob.month >> aStudent.dob.year >> aStudent.scores[0] >> 
aStudent.scores[1] >> aStudent.scores[2] >> aStudent.scores[3] >> aStudent.scores[4] >> aStudent.scores[5];


Since the file is open, we read values into aStudent, then the 5 scores into an array of scores (I'm assuming that your NUM_SCORES variable is = 5)


D
1
2
3
cout << "Student Number\t" << "DOB\t\t" << "Student Scores" << endl; 
	for (int i = 0; i < 15; i++)
	{


output " Student Number DOB Student Scores\n"
Then start a loop of the following code, loop 15 times.

E
1
2
3
cout << aStudent.number << "\t\t" << aStudent.dob.day <<"/" <<aStudent.dob.month <<"/" << aStudent.dob.year <<"\t"<< 
aStudent.scores[0] << aStudent.scores[1] << aStudent.scores[2] << aStudent.scores[3]<< aStudent.scores[4] << aStudent.scores[5]<< endl;	   
}


(edit, lol) we now input the next bits into our variables without outputting them. 15 times.

F

infile.close();

And now we close infile, please note that this is within your while loop, so infile.eof() will return true next turn, or segfault. So you can't read more data from the file here.
Last edited on
thanks for explaining all that but that's not the problem I'm having. the text file is only showing the last line 15 times. I need to do something like whitenite1 was saying but student aStudent won't work so I need to know what will
Oh my word.
.....what?
i know it might seem like a stupid question but i am i beginner and i cant figure out this one bit
Last edited on
It's not a stupid question, do you have more code after that infile.close();? You're missing an end brace for your while loop.
heres all the code again:
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
#include "stdafx.h"
using namespace std;

const int NUM_SCORES = 6;
const int MAX_ITEMS = 15;

typedef struct 
 {
	int day;
	int month;
	int year;
 } Date; 

typedef struct 
 {
	int number;
	Date dob;
	float scores[NUM_SCORES];
 } Student;

typedef Student ItemType; //change ItemType from int to Student

struct ListType 
{
	int length;
	ItemType info [MAX_ITEMS];
};

 ListType list;
 ItemType aStudent, findStudent;

int _tmain(int argc, _TCHAR* argv[])
{

fstream infile;
 infile.open(name);
 int n = 0;
       while (!infile.eof()) 
	for (int i = 0; i < 15; i++)
	{
	infile >> aStudent[n].number >> aStudent[n].dob.day >> aStudent[n].dob.month >> aStudent[n].dob.year >> aStudent[n].scores[0] >> 
aStudent[n].scores[1] >> aStudent[n].scores[2] >> aStudent[n].scores[3] >> aStudent[n].scores[4] >> aStudent[n].scores[5];
             n++;
}infile.close();
cout << "Student Number \t"  << " DOB\t\t" << "Student Scores" << endl; 
	for (int i = 0; i < 15; i++)
	{
	cout << aStudent[i].number << "\t\t" << aStudent[i].dob.day <<"/" <<aStudent[i].dob.month <<"/" << aStudent[i].dob.year <<"\t"<< 
aStudent[i].scores[0] << aStudent[i].scores[1] << aStudent[i].scores[2] << aStudent[i].scores[3]<< aStudent[i].scores[4] << aStudent[i].scores[5]<< endl;	   
          } 
}
Last edited on
@kw1991

I tweaked the program a bit, now it will load the students and print them out. It won't matter if you have 1 student or 15, because I used while loops. Hope this helps out.

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
60
61
// aStudent.cpp : Defines the entry point for the console application.

#include <stdafx.h>
#include <stdio.h>
#include <conio.h>
#include <iostream>
#include <fstream>
#include <string>
#include <windows.h>

using namespace std;

const int NUM_SCORES = 6;
const int MAX_ITEMS = 15;

ifstream infile("aStudent.txt");

struct Date 
{
	int day;
	int month;
	int year;
}; 

struct Student
{
	int number;
	Date dob;
	float scores[NUM_SCORES];
}aStudent[MAX_ITEMS];



int main()
{
	int n = 0;
	while (infile >> aStudent[n].number >> aStudent[n].dob.day >> aStudent[n].dob.month >> aStudent[n].dob.year >> aStudent[n].scores[0] >> 
				aStudent[n].scores[1] >> aStudent[n].scores[2] >> aStudent[n].scores[3] >> aStudent[n].scores[4] >> aStudent[n].scores[5]) 
		{
			n++;
		};
int i=0;
	cout << "Student Number\tDOB (DD/MM/YYYY)\tStudent Scores" << endl;
	cout << "--------------\t----------------\t--------------" << endl << endl; 
do
	{
		cout << "\t";
		if ( aStudent[i].number < 10)
			cout << " ";
		cout << aStudent[i].number << "\t";
		if (aStudent[i].dob.month < 10)
			cout << "0";
		cout << aStudent[i].dob.month <<"-";
		if (aStudent[i].dob.day < 10)
			cout << "0";
		cout << aStudent[i].dob.day <<"-" << aStudent[i].dob.year <<"\t\t"<< 
			aStudent[i].scores[0] << " " << aStudent[i].scores[1] << " " << aStudent[i].scores[2] << " " << aStudent[i].scores[3] << " " << 
			aStudent[i].scores[4] << " " << aStudent[i].scores[5]<< endl;
		i++;
	} while (aStudent[i].number ); 
}
Last edited on
1
2
3
4
5
6
7
cout << "Student Number \t"  << " DOB\t\t" << "Student Scores" << endl; 
	for (int i = 0; i < 15; i++)
	{
	cout << aStudent[i].number << "\t\t" << aStudent[i].dob.day <<"/" <<aStudent[i].dob.month <<"/" << aStudent[i].dob.year <<"\t"<< 
aStudent[i].scores[0] << aStudent[i].scores[1] << aStudent[i].scores[2] << aStudent[i].scores[3]<< aStudent[i].scores[4] << aStudent[i].scores[5]<< endl;	   
          } 
}


KK, well I'll explain what your problem is exactly, you can fix it pretty easily.

Please note that here you are outputting your variables 15 times, and

1
2
3
4
5
6
for (int i = 0; i < 15; i++)
	{
	infile >> aStudent[n].number >> aStudent[n].dob.day >> aStudent[n].dob.month >> aStudent[n].dob.year >> aStudent[n].scores[0] >> 
aStudent[n].scores[1] >> aStudent[n].scores[2] >> aStudent[n].scores[3] >> aStudent[n].scores[4] >> aStudent[n].scores[5];
             n++;
}


here you're inputting your variables 15 times, EVERY single time you're over-writing the old values inside those variables, and putting the new values inside. So you end up copying all of the variables, then overwriting them with the next set, all the way to the end. Now, if you were to change this (first for loop) to :

1
2
3
4
5
6
7
8
9
while(!infile.eof())
	{
	infile >> aStudent[n].number >> aStudent[n].dob.day >> aStudent[n].dob.month >> aStudent[n].dob.year >> aStudent[n].scores[0] >> 
aStudent[n].scores[1] >> aStudent[n].scores[2] >> aStudent[n].scores[3] >> aStudent[n].scores[4] >> aStudent[n].scores[5];
             n++;

       cout << aStudent[i].number << "\t\t" << aStudent[i].dob.day <<"/" <<aStudent[i].dob.month <<"/" << aStudent[i].dob.year <<"\t"<< 
aStudent[i].scores[0] << aStudent[i].scores[1] << aStudent[i].scores[2] << aStudent[i].scores[3]<< aStudent[i].scores[4] << aStudent[i].scores[5]<< endl;
}


it would work as expected.
there is still an error with [n] it says no operator "[]" matches these operands
@kw1991

Are you referring to my answer, or about ultifinitus's? I do not believe it's mine, since I have it running in MS Visual C++ 2008 Express, as is.
Pages: 12