What is wrong with my toupper loop?

Hi,

My program is running good I'm just having trouble with my toupper loop. Every time I run the program, the program fails. Can someone help me figure out what's wrong
#include<iostream>
#include<string>


using namespace std;

struct student
{
string name;
char gender;
float grade;

};

void main()
{
student stud[24];
int nbstuds;
string results, gender;


cout << "\tLASALLE COLLEGE\n";
cout << "\t---------------\n";
do
{
cout << "Enter the number of students (max 25) : ";
cin >> nbstuds;
} while (nbstuds <= 0 || nbstuds > 25);





for (int i = 0; i < nbstuds; i+=1)
{

cout << "Student " << i+1 << endl;
do
{
cout << " Name : ";
cin.ignore();
getline(cin, stud[i].name);
} while (stud[i].name == "");
do
{

cout << " Gender : ";
cin >> stud[i].gender;

} while (!(stud[i].gender == 'm' || stud[i].gender == 'M' || stud[i].gender == 'f' || stud[i].gender == 'F'));
do
{
cout << " Grade : ";
cin >> stud[i].grade;

} while (stud[i].grade < 0 || stud[i].grade > 100);




}





for (int a = 0; 1 < stud[a].name[a]; ++a)
{
if (a == 0)
{
stud[a].name[a] = toupper(stud[a].name[a]);
}
else if (stud[a].name[a - 1] == ' ')
{
stud[a].name[a] = toupper(stud[a].name[a]);
}
}





cout << "Students Names\t\tGrades\t\tResults\n";

for (int i = 0; i < nbstuds ; i++)
{
stud[i].gender = toupper(stud[i].gender);

gender = (stud[i].gender == 'M') ? "Sir" : "Miss";

results = (stud[i].grade >= 60) ? "Pass" : "Fail";

cout << gender << " " << stud[i].name << "\t\t" << stud[i].grade << "\t\t" << results << endl;
}


system("pause");
}
This part makes no sense: for (int a = 0; 1 < stud[a].name[a]; ++a)
Explain what you are trying to do in non-programming terms with this loop.

stud[a].name[a] is a character, so you're comparing 1 < ascii value of letter, which doesn't make sense.

If you are looping through ever character of every student, then you need 2x loops; for loop within for loop, and separate iteration variables.
Last edited on
Please format your code before posting and use code tags - so that we can read it!

As formatted:

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
#include <iostream>
#include <string>

using namespace std;

struct student
{
	string name;
	char gender;
	float grade;
};

void main()
{
	student stud[24];
	int nbstuds;
	string results, gender;

	cout << "\tLASALLE COLLEGE\n";
	cout << "\t---------------\n";

	do
	{
		cout << "Enter the number of students (max 25) : ";
		cin >> nbstuds;
	} while (nbstuds <= 0 || nbstuds > 25);

	for (int i = 0; i < nbstuds; i += 1)
	{
		cout << "Student " << i + 1 << endl;

		do
		{
			cout << " Name : ";
			cin.ignore();
			getline(cin, stud[i].name);
		} while (stud[i].name == "");

		do
		{
			cout << " Gender : ";
			cin >> stud[i].gender;
		} while (!(stud[i].gender == 'm' || stud[i].gender == 'M' || stud[i].gender == 'f' || stud[i].gender == 'F'));

		do
		{
			cout << " Grade : ";
			cin >> stud[i].grade;

		} while (stud[i].grade < 0 || stud[i].grade > 100);
	}

	for (int a = 0; 1 < stud[a].name[a]; ++a)
	{
		if (a == 0)
		{
			stud[a].name[a] = toupper(stud[a].name[a]);
		} else if (stud[a].name[a - 1] == ' ')
		{
			stud[a].name[a] = toupper(stud[a].name[a]);
		}
	}

	cout << "Students Names\t\tGrades\t\tResults\n";

	for (int i = 0; i < nbstuds; i++)
	{
		stud[i].gender = toupper(stud[i].gender);
		gender = (stud[i].gender == 'M') ? "Sir" : "Miss";
		results = (stud[i].grade >= 60) ? "Pass" : "Fail";

		cout << gender << " " << stud[i].name << "\t\t" << stud[i].grade << "\t\t" << results << endl;
	}

	system("pause");
}


Also note that when using toupper() [or tolower et al], the parameter and the returned value should be cast as for example:

 
static_cast <char>(toupper(static_cast<unsigned int>(stud[i].gender)));


See https://en.cppreference.com/w/cpp/string/byte/toupper
Last edited on
I don't think a beginner should worry about that latter part (muddying the waters).
Last edited on
main() should return int, not void.

It looks like you're trying to convert the names to upper case, but you're doing it after inputting them all. This confused you because you actually need to convert each character of each name, which requires two nested loops. You only have one. In general I find it best to convert input from "human friendly" form to "computer friendly" form as soon as possible - right after you input it. Also, converting to upper case is a great example of the benefits of range-based for loops:
1
2
3
4
5
6
7
8
9
10
        do {
            cout << " Name : ";
            cin.ignore();
            getline(cin, stud[i].name);
        } while (stud[i].name == "");

        // Convert name to upper case
        for (char &ch : stud[i].name) {
            ch = toupper(ch);
        }


You can see why it helps to convert the input right away in the check for gender. See how much easier this is?
1
2
3
4
5
        do {
            cout << " Gender : ";
            cin >> stud[i].gender;
            stud[i].gender = toupper(stud[i].gender);
        } while (!(stud[i].gender == 'M' || stud[i].gender == 'F'));


And then in the output, you don't have to worry about whether gender is upper or lower case because you've already converted it:
1
2
3
4
5
6
7
    for (int i = 0; i < nbstuds; i++) {
        gender = (stud[i].gender == 'M') ? "Sir" : "Miss";
        results = (stud[i].grade >= 60) ? "Pass" : "Fail";

        cout << gender << " " << stud[i].name << "\t\t"
             << stud[i].grade << "\t\t" << results << endl;
    }

Topic archived. No new replies allowed.