Really need help! Getting an error....and a weird output.

I have a completed code below. I'm getting a weird output for my program and then it errors out with a error saying
Run-Time Check Failure #2 - Stack around the variable 'gpa_aux' was corrupted.

Here is a little background of how the program should run.
My program should be able to read from a file the above data into an array and sort the array by the student’s name in an ascending order. Selection sort algorithm is strongly recommended on the array of objects. And also the record office would like to have a sorted class list for each class, freshman, sophomore, junior, and senior.

Here is my code:

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
 //the file prog1.txt must to have format according to

//Each line in the data file should contain a student’s name in



#include <fstream> /* for file i/o */
#include <iostream> /* interactive i/o*/
#include <string>   // substr
using namespace std;


//here is defined the class

class Cstudent
{
private:
	/*data of the class*/
	char NAME[20], STANDING[10], GPA[5]; // first is the type, second the name

public:
	//functions of the class Cstudent
	void name(char a[20]) //asign the value of A to name
	{
		for (int i = 0; i<20; i++)
		{
			NAME[i] = a[i];
		}
		cout << NAME;
		cout << "\n";
	}
	void standing(char b[10]) //asign the value of b to standing
	{
		for (int i = 0; i<10; i++)
		{
			STANDING[i] = b[i];
		}
	}
	void gpa(char c[5]) //asign the value of c to GPA
	{
		for (int i = 0; i<5; i++)
		{
			GPA[i] = c[i];
		}
	}
	char give_standing()
	{
		return STANDING[0];
	}
	char give_name()
	{
		return NAME[0];
	}
};

//the function swap interchanges the values of string of students

void swap(Cstudent stdt1, Cstudent stdt2)
{
	Cstudent temp = stdt1;
	stdt1 = stdt2; // Swap two students’ records
	stdt2 = temp;
}

int main() {


	Cstudent students[25], fresh[25], soph[25], jun[25], sen[25]; /* the arrays of students (objects) */
	char s[35], name_aux[20], standing_aux[10], gpa_aux[5];
	ifstream infile("students.txt"); // read student data from the file
	for (int i = 0; i<24; i++)       // read line by line; 25 lines
	{
		infile.getline(s, 40); // put each line in the "s" variable
							   // cout<< s; //this prints are from tests
							   // cout<<"\n";
		for (int j = 0; j<20; j++) //in this cycles descompose the variable s
		{
			name_aux[j] = s[j]; // the firsts 20 values goes to name
		}
		int k = 0;
		for (int j = 20; j<30; j++) //between 20 and 30 goes to standing
		{
			k = k + 1; // k is an auxiliar variable to initialize the count
			standing_aux[k] = s[j];
		}
		k = 0;
		for (int j = 30; j<35; j++) // and the gpa
		{
			k = k + 1;
			gpa_aux[k] = s[j];
		}
		students[i].name(name_aux); //call the function to asign the value taken of each line
		students[i].standing(standing_aux);
		students[i].gpa(gpa_aux);
		// cout<<name_aux; //this print is for test


	}
	/* Use Selection sort to sort the array */
	int i, j, k = 0;
	char temp; //variable referential to sort
	for (i = 0; i<25; i++)
	{
		temp = students[i].give_name();
		j = 1;
		for (j = i + j; j<26; j++)
		{
			// cout<<(temp >= students [j].give_name());
			if (temp >= students[j].give_name())

			{
				temp = students[j].give_name();
				k = j;
				swap(students[i], students[k]);
			}
		}

	}

	/* copying freshman, sophomore, junior and senior
	Fresh =freshman list
	Soph = sophomore list
	Jun=junior list
	Sen=senior list */

	/*to select the standing */

	int fr = 0, so = 0, ju = 0, se = 0; /*fr=freshman index, so=sophomore index, ju=junior index, se=senior index*/

	for (i = 0; i<25; i++)
	{
		switch (students[i].give_standing())
		{

		case 'r': //freshman llist/
			fresh[fr++] = students[i];
			break;
		case 'o': // sophomore list
			soph[so++] = students[i];
			break;
		case 'u': //junior list
			jun[ju++] = students[i];
			break;
		case 'e': // senior list
			sen[se++] = students[i];
			break;
		}
		// cout<<students[i].give_name();
	}

	system("break");
	return 0;

}

/* the results are not the better, i think is better to try whit string, not with char,

it is nescesary to adjust the sort algoritm */

I'm not understanding why this is happening the code looks fine to me.Any help would be appreciated.
Last edited on
1
2
3
4
5
		for (int j = 30; j<35; j++) // and the gpa
		{
			k = k + 1;
			gpa_aux[k] = s[j];
		}
When j == 30, accesses gpa_aux[1]
j == 31, gpa_aux[2]
j == 32, gpa_aux[3]
j == 33, gpa_aux[4]
j == 34, gpa_aux[5]

As ypur gpa_aux has only 5 elements with valid indices 0-4, that access is invalid.
@MiiNiPaa So should I change the gpa_aux to 6?

Edited: I'm going to go through the code to make sure every part is working as it should. So far the it is reading the file correctly.

Edited(2): So the problem seems to be when I get to the first for loop. I'm trying to figure out the problem here?
Last edited on
You seem to know about the std::string class, I suggest you start using it.

Part of you problems is that you don't seem to understand the bounds of arrays. Look at this snippet:

1
2
3
4
5
	char s[35], name_aux[20], standing_aux[10], gpa_aux[5];
	ifstream infile("students.txt"); // read student data from the file
	for (int i = 0; i<24; i++)       // read line by line; 25 lines
	{
		infile.getline(s, 40); // put each line in the "s" variable 


First you have declared s with a size of 35, yet you allow the user to enter up to 40 characters. This is a possible out of bounds access. If you used std::strings instead you wouldn't be having problems like this.

Second what happens if the file fails to open? You should always check that the fie opens correctly and take some action if it doesn't.
@jlb would I use something like substr. So....
1
2
3
4
5
6
7
8
9
for(int i=0; i<24;i++)
{
     infile.getline(s,80)
     cout<<s;
     substr(s,0,20,students[i].name);
     substr(s,20,10,students[i].class);
     substr(s,30,4,students[i].gpa);

}


Maybe something like that? At this point I have tried everything. And the more I change it. The more I confuse myself.
Last edited on
Why is s still a C-string? It should be a string if you want to use substr(). So should the other variables in that snippet name, class, and gpa. And be careful class is a C++ keyword so shouldn't be used as the name of a variable.
1
2
3
4
5
6
7
8
9
10
11
std::string s;

for(int i=0; i<24;i++)
{
     getline(infile, s); // Use the string version of getline().
     cout<<s;
     substr(s,0,20,students[i].name);
     substr(s,20,10,students[i].class);
     substr(s,30,4,students[i].gpa);

}


And you should be using named constants instead of magic numbers like 24, 20 10 and the like.

Also there may be better ways of parsing a line other than using substr(). But without knowing the format of the input file this is only a guess.



In my code I have class as STANDING. I'm trying to enter the code the way you have it above. But visual studios doesn't like getline(infile,s);. It keeps giving me an error for getline.
Last edited on
What exactly is the error?

It has that red line under getline and when I hover over the line it says
Error no instance of overload function "getline" matches argument list
Last edited on
Don't rely on intellinonsense errors compile your code and report the actual compile errors.
Topic archived. No new replies allowed.