Function only works if I use constant variable - why?

I have a program with a few functions, for example one to display records and one to read them from a text file.

When reading them from a text file, if I use a control variable, let's say x, when I then call my display() function, nothing is displayed, it's as if the records weren't stored in the array. However if I use a constant variable I have, currentSize, it works fine. The records are read in from the text file, stored in the global array, and displayed by the display() function.

Here's the 2 functions, when they work, where currentSize is a global constant variable I use to keep track of the size of my array:

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
void displayStudents()
{
	int a;

	system("cls");
	
	cout << "Matric No" << setw(7) << "Name" << setw(12) << "Status" << setw(6) << "Mark" << endl;
	
	for(a = 0; a < currentSize; a++)
	{
		cout << setw(4) << studentRecords[a].matricNo;
		cout << setw(12) << studentRecords[a].name;
		cout << setw(10) << studentRecords[a].status;
		cout << setw(6) << studentRecords[a].mark << endl;
	}

	cin.get();
}

int readFromFile()
{
	currentSize = 0;
	ifstream myInputFile("test.txt");

	if(!myInputFile)
	{
		cout << "File failed to open" << endl;
		cin.get();
		return 1;
	}

	while(!myInputFile.eof())
	{
		getline(myInputFile,studentRecords[currentSize].matricNo);
		getline(myInputFile,studentRecords[currentSize].name);
		getline(myInputFile,studentRecords[currentSize].status);
		myInputFile >> studentRecords[currentSize].mark;
		myInputFile.get();

		currentSize++;
	}

	myInputFile.close();

	currentSize--;

	return 0;
}


But, in the readFromFile() function, if I change it to:

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
int readFromFile()
{
	int x = 0;
	ifstream myInputFile("test.txt");

	if(!myInputFile)
	{
		cout << "File failed to open" << endl;
		cin.get();
		return 1;
	}

	while(!myInputFile.eof())
	{
		getline(myInputFile,studentRecords[x].matricNo);
		getline(myInputFile,studentRecords[x].name);
		getline(myInputFile,studentRecords[x].status);
		myInputFile >> studentRecords[x].mark;
		myInputFile.get();

		x++;
	}

	myInputFile.close();

	x--;

	return 0;
}


it would seem that the records are "read in", but when I call the display() function, nothing is shown, it's as if after reading in from the text file the values aren't being stored in the array.

Just wondered why this should be the case, it's really baffled me.

Thanks
Last edited on
currentSize = 0;

If this compiles, currentSize is certainly not a constant. I'd like to see how you declared it. If it's int currentSize = 0;, that would explain a lot.

Incidentally, but importantly, never loop on eof(). Do this instead:

while(myInputFile)

because this will test for good(), which is the only state you want your stream to be in when you're going to use it.
The size of an array should always be constant. In both examples how are you declaring the studentRecords struct?

EDIT: To build on what filipe said. If you are only testing for End of File then your loop will continue even if other errors or exit conditions are met.
Last edited on
Thanks guys, maybe the whole code will help. And currentSize wasn't a constant, sorry, I meant global variable, not constant. Also, everything I do has been taught to us by our University lecturer, but I'm starting to doubt him - after doing my own learning and research by looking online, buying books, etc, I realise he's teaching us some bad habits (using system("cls"), having main as void(), etc)

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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
#include <iostream>
#include <string>
#include <iomanip>
#include <fstream>

using namespace std;

struct student
{
	string matricNo;
	string name;
	string status;
	int mark;
};

const int TOTALSIZE = 30;
int currentSize = 0;
student studentRecords[TOTALSIZE];

void addStudent();
void displayStudents();
void searchStudent();
int writeToFile();
int readFromFile();

int main()
{
	int option = 0;
	bool endOfSession = false;
	
	while(!endOfSession)
	{
		system("cls");

		cout << "1: Add student" << endl;
		cout << "2: Display students" << endl;
		cout << "3: Search students" << endl;
		cout << "4: Output to file" << endl;
		cout << "5: Read from file" << endl;
		cout << "0: Quit" << endl << endl;
		cout << "Choose an option: ";
		cin >> option;
		cin.get();

		switch(option)
		{
			case 1:		addStudent();
						break;
			case 2:		displayStudents();
						break;
			case 3:		searchStudent();
						break;
			case 4:		writeToFile();
						break;
			case 5:		readFromFile();
						break;
			case 0:		endOfSession = true;
						cout << endl << "Quit" << endl << endl;
						break;
			default:	cout << "You have entered an invalid option";
		}
	}
}

void addStudent()
{
	int a, noToAdd;

	system("cls");

	cout << "How many students do you wish to add?: ";
	cin >> noToAdd;
	cin.get();

	for(a = 0; a < noToAdd; a++)
	{
		cout << "Enter matriculation number: ";
		getline(cin,studentRecords[currentSize].matricNo);
		cout << "Enter name: ";
		getline(cin,studentRecords[currentSize].name);
		cout << "Pass or Fail?: ";
		getline(cin,studentRecords[currentSize].status);
		cout << "Enter mark: ";
		cin >> studentRecords[currentSize].mark;
		cin.get();

		system("cls");
		
		currentSize++;
	}
}

void displayStudents()
{
	int a;

	system("cls");
	
	cout << "Matric No" << setw(7) << "Name" << setw(12) << "Status" << setw(6) << "Mark" << endl;
	
	for(a = 0; a < currentSize; a++)
	{
		cout << setw(4) << studentRecords[a].matricNo;
		cout << setw(12) << studentRecords[a].name;
		cout << setw(10) << studentRecords[a].status;
		cout << setw(6) << studentRecords[a].mark << endl;
	}

	cin.get();
}

void searchStudent()
{
	int a;
	string searchType;
	string nameToFind, matricNoToFind;
	bool found = false;

	system("cls");

	cout << "Search by Name or Matriculation number? (enter n or m): ";
	cin >> searchType;
	cin.get();

	
	if(searchType == "n")
	{
		cout << endl << "Enter name to find: ";
		getline(cin,nameToFind);
		
		for(a = 0; a <= currentSize; a++)
		{
			if(studentRecords[a].name == nameToFind)
			{
				cout << endl << "Found";
				found = true;
				cin.get();
				break;
			}
		}

		if(!found) cout << "Not found";
		cin.get();
	}
	else if(searchType == "m")
	{
		cout << endl << "Enter matric # to find: ";
		getline(cin,matricNoToFind);
		
		for(a = 0; a <= currentSize; a++)
		{
			if(studentRecords[a].matricNo == matricNoToFind)
			{
				cout << endl << "Found";
				found = true;
				cin.get();
				break;
			}
		}

		if(!found)
		{
			cout << "Not found";
			cin.get();
		}
	}
}

int writeToFile()
{
	int a;
	ofstream myOutputFile("test.txt");

	if(!myOutputFile)
	{
		cout << "File failed to open" << endl;
		return 1;
	}

	for(a = 0; a < currentSize; a++)
	{
		myOutputFile << studentRecords[a].matricNo << endl;
		myOutputFile << studentRecords[a].name << endl;
		myOutputFile << studentRecords[a].status << endl;
		myOutputFile << studentRecords[a].mark << endl;
	}

	myOutputFile.close();

	return 0;
}

int readFromFile()
{
	currentSize = 0;
	ifstream myInputFile("test.txt");

	if(!myInputFile)
	{
		cout << "File failed to open" << endl;
		cin.get();
		return 1;
	}

	while(!myInputFile.eof())
	{
		getline(myInputFile,studentRecords[currentSize].matricNo);
		getline(myInputFile,studentRecords[currentSize].name);
		getline(myInputFile,studentRecords[currentSize].status);
		myInputFile >> studentRecords[currentSize].mark;
		myInputFile.get();

		currentSize++;
	}

	myInputFile.close();

	currentSize--;

	return 0;
}
Last edited on
This program should really be done with a std::vector, I suggest you look it up. There's no need to use arrays directly.

Anyway, here's your problem: when you use local variable x instead of the global currentSize, you never change currentSize's value. Therefore, when you call displayStudents(), currentSize == 0, so the for loop will never execute.

Notice that this program will crash if your file has more than TOTALSIZE entries. A std::vector would prevent that, as it keeps track of its size, allowing you to use it in the for loop.
Topic archived. No new replies allowed.