Help with homework (arrays + structures)

I am being asked to make a program that takes student profiles from a user, calculate the GPAs of the students, sort their names by their last names...
Anyways, I got some of the code...I'm missing the last part (sorting part)
I don't really care much for condensing my code into a shorfer version especially if I'm not going to understand it.

Here's what I got:
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
#include <iostream>
using namespace std;

struct Class
{
	char title[100];
	int units;
	char grade;
};

struct Student
{
	char name[100];
	double GPA;
	Class classes[100];
};

void initialize(Student[], int);
void read(Student[], int);
void GPAs(Student[], int);
void display(Student[], int);
//void sort_name(Student[], int); For the sort function see #2

int main()
{
	Student profile[50];
	int size = 50;

	initialize(profile, size);
	read(profile, size);
	GPAs(profile, size);
	display(profile, size);
	//sort_name(profile, size); for the sort function...see #2
	system("pause");
	return 0;
}
void initialize(Student profile[], int size)//I was asked to set GPAs to 0.0
{
	for(int i = 0; i < size; i++)
	{
		profile[i].GPA = 0.0;
	}

}
void read(Student profile[], int size)//Where user inputs info
{
	for(int i = 0; i < size; i++)
	{
		cout<<"Enter student's name: ";
		cin.getline(profile[i].name, 100, '\n');
		
		for(int j = 0; j < 100; j++)
		{
			if(profile[i].name[j] == ' ')
			{
				if(isupper(profile[i].name[j+1]) == false)
					toupper(profile[i].name[j+1]);
			}
		}

		if(profile[i].name[0] == '\0')//I'm having issues here 
		{                             //See #1 at the bottom
			break;               //for more info
		}

		for(int c = 0; c < 100; c++)
		{
			cout<<"\nEnter class name: ";
			cin.getline(profile[i].classes[c].title, 100, '\n');

			if(profile[i].classes[c].title == '\0')//Again,
			{                                      //same thing
				break;                        //see #1
			}

			cout<<"Enter number of units: ";
			cin>>profile[i].classes[c].units;

			cout<<"Enter letter grade: ";
			cin>>profile[i].classes[c].grade;

			if(islower(profile[i].classes[c].grade))
				toupper(profile[i].classes[c].grade);

			cin.ignore();
		}
	}
}
void GPAs(Student profile[], int size)// Calculates GPAs of the students
{
	int totalunits, worth, sum;

	for(int i = 0; i < size; i++)
	{
		totalunits = 0;
		sum = 0;
		for(int c = 0; c < 100; c++)
		{
			totalunits += profile[i].classes[c].units;

			if(profile[i].classes[c].grade == 'A')
				worth = 4;
			else if(profile[i].classes[c].grade == 'B')
				worth = 3;
			else if(profile[i].classes[c].grade == 'C')
				worth = 2;
			else if(profile[i].classes[c].grade == 'D')
				worth = 1;
			else
				worth = 0;

			sum += (worth * profile[i].classes[c].units);
		}

		profile[i].GPA = sum/totalunits;
	}

}
void display(Student profile[], int size) //supposed to display the array
{                                         //not sure if it works because
	for(int i = 0; i < 50; i++)      //I can't get past inputting 
	{                                //because I cant stop the program
		cout<< "Student name: " //from asking info so, see #1
			<< profile[i].name;
		for(int j = 1; j <= 100; j++)
		{
			cout<<"\n\tName of Class #"<<j<<": "
				<<profile[i].classes[j].title
				<<"\n\tAmount of units: "
				<<profile[i].classes[j].units
				<<"\n\tLetter grade: "
				<<profile[i].classes[j].grade;
		}

		cout<<profile[i].GPA<<"\n\n";
	}

}


#1 issue
- I am asked to make the program stop asking for more student names when the user only enters a new line(uses the enter/return key). The same thing goes for entering classes. My code doesn't seem to stop asking for names.

#2 issue
- I am being asked to sort the names by their last name. The names are being entered in such a way that First name + space + last name is entered. I don't know how to sort the names. Please help me...all I know is it involves checking for space characters and compare the next character to the next names's character after the space but I just can't figure it out let alone put it into a code.

Please help...
Last edited on
New BREAKTHROUGH!!!
Issue #1
- I'm not having trouble with the stopping the user from inputting an item. Rather, I'm having issues with displaying it. When the user enters only a new line on the "enter student name: " line, the program just goes crazy and won't stop looping and displaying tons of symbols and -894567 (or something like that) for the units and stuff.

Issue #2
- Since I can't test it...I'm going to show my code here. So far, my compiler/builder hasn't said anything wrong with my code. So, I'm going to just post it here anyways...

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
void sort_name(Student profile[], int size2)
{
	Student hold;

	for(int i = 0; i < size2; i++)
	{
		for(int j = 0; j < 100; j++)
		{
			if(profile[j].name[j] == ' ')
			{
				if(isupper(profile[i].name[j+1]) == false)
					toupper(profile[i].name[j+1]);
			}
		}
	}

	for(int i = 0; i < size2; i++)
	{
		int x = 1;
		for(int j = 0; j < 100; j++)
		{
			if(profile[i].name[j] == ' ')
			{
				for(int k = 1; k < size2; k++)
				{
					for(int h = 0; h < 100; h++)
					{
						if(profile[k].name[h] == ' ')
						{
							if((int)profile[i].name[j+x] > (int)profile[k].name[h+x])
							{
								hold = profile[i];
								profile[i] = profile[k];
								profile[k] = hold;
							}
							else
							{
								while((int)profile[i].name[j+x] == (int)profile[k].name[h+x])
								{
									x++;
									if((int)profile[i].name[j+x] > (int)profile[k].name[h+x])
									{
										hold = profile[i];
										profile[i] = profile[k];
										profile[k] = hold;
									}
								}
							}
						}
					}
				}
			}
		}
	}
}


This is a bubble sort...kind of, I guess...
Issue #1 - when the user just presses return, only the part of the profile array of Student records up to that point will be valid. But GPAs() and display() are both still running through the whole array.

Cheers,
Jim
THANKS!!!
Unfortunately, I can't fix it.
I tried adding " if(strcmp(profile[i].name, "") != 0)" and breaks for the else after that, it still goes crazy...
Wow, it looks like you are doing alot of work when you might not have to. Why store names as a character array if it isn't going to be null terminated (c-style string)? Wouldn't you rather a std::string and then just read char by char to limit the max number of chars?

1
2
3
4
5
6
7
8
9
10
11
         char buff;
        
	cout<<"Enter student's name: ";
	cin.get(buff);
	
       for (int i = 0; buff != '\n' and i < 100; i++) {     
		profile[i].name += buff;	
		cin.get(buff);
	}

        cin.ignore(256, '\n');  // flush the stream 


I would use the C++ string class methods #include <string> to find the last whitespace and extract the last name in a function that can be called in you sort function.

1
2
3
4
5
6
7
8
9

string GetLastName(string fullName) { 

        int index = profile[i].find_last_of(' ');	

	if (index != string::npos)   // if more than one name was entered
		return profile[i].name.substr(index+1, profile[i].name.size());    // return the lastname 
}       


You can then just simply pass the function a profile[i].name and it will return the lastname. (only if you store name as a std::string)


With the lastnames you can write the real bubble sort algorithm and since std::string has built-in logical operators you can just use the < operator on the last names at your leisure.


Hope this helps
Last edited on
Topic archived. No new replies allowed.