help with my inputs (c-string)

Hey everyone, I need a bit of help with my program.
For starters, whenever I input a class title that has a number for example: "Math 102"
the add() function only takes the title and skips the units and then asks for the grade received. It works when inputting a class title without numbers, For example: Math. Everything then works fine.

Another quick question I have is in the edit() function.
You're supposed to select an index for the class you want to edit, once the user inputs what class the want to edit it's supposed to display for example:

"Editing: Math 102, 3 units, Grade: B"
How would I go about displaying the class the user is currently editing

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
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
#include <iostream>
#include <cstdlib>
#include <sstream>
#include <string>
#include <cstring>
#include <fstream>
#include <iomanip>
#include <cstddef>

using namespace std;

#define MAX 10

struct Class {

	char title[30];

	int units;

	char grade;

};

typedef struct Class ClassType;

int bin_search(ClassType *classPointer[], int l, int r, char title[30]);

void sort(ClassType *classPointer[]);

int find_allocated_size(ClassType *classPointer[]);

void list_all_Classes(ClassType *classPointer[]);

 

int showMenu() {

	cout << "1. Add new class " << endl;

	cout << "2. Edit an existing class" << endl;

	cout << "3. Display a class" << endl;

	cout << "4. List all classes " << endl;

	cout << "5. Display GPA" << endl;

	cout << "6. Delete all classes" << endl;

	cout << "7. Quit" << endl;

	cout << "Enter selection number: ";

	int choice;

	cin >> choice;

	while (cin.fail())

	{

		cin.clear();

		cin.ignore(1000, '\n');

		cout << "Error: Please enter a number " << endl;

		cin >> choice;

	}

	return choice;

}

void add(ClassType *classPointer[]) {

	char title[30];

	int units;

	char grade;

	int content_flag = 0;

	cout << "Enter class name: ";
	cin >> title;
	
	cout << "Enter number of units: ";
	cin >> units;
	
	cout << "Enter grade receive: ";
	cin >> grade;
	

	for (int i = 0; i< MAX; i++) {

		if (classPointer[i] == NULL) {

			classPointer[i] = (ClassType *)malloc(sizeof(ClassType));

			strcpy_s(classPointer[i]->title, title);

			classPointer[i]->units = units;

			classPointer[i]->grade = grade;

			content_flag = 1;

			break;

		}

	}

	if (content_flag == 1) {

		cout << "Select one of the following actions:" << endl;

	}

	else {

		cout << "data is not added to Class Structure" << endl;

	}

}

void edit(ClassType *classPointer[]) {

	

	list_all_Classes(classPointer);

	cout << "Please enter index to edit" << endl;

	int user_index;

	cin >> user_index;

	if (user_index < 0 || user_index > find_allocated_size(classPointer)) {



		cout << "Index specified is out of range" << endl;

		return;

	}

	else {
		
		
		char title[30];

		int units;

		char grade;

		cout << "Editing: ";
		cout << title, units, grade;



		cout << "Enter class name: ";
		cin >> title;
		cout << "Enter units: ";
		cin >> units;
		cout << "Enter grade: ";
		cin >> grade;

		

		strcpy_s(classPointer[user_index]->title, title);

		classPointer[user_index]->units = units;

		classPointer[user_index]->grade = grade;

		cout << "Class modified" << endl;

	}

}

void list_all_Classes(ClassType *classPointer[]) {



	for (int i = 0; i< MAX; i++) {

		if (classPointer[i] != NULL) {

			cout << i << "\t" << classPointer[i]->title << "\t" << classPointer[i]->units << " units" << "\t" <<", grade: "<< classPointer[i]->grade << endl;

		}

	}

}

void display_single_Class(ClassType *classPointer[]) {

	if (find_allocated_size(classPointer) == 0) {

		cout << "No contents in the structure to search" << endl;

		return;

	}

	char title[30];

	cout << "Enter the class title";

	cin >> title;

	sort(classPointer);

	int allocated_size = find_allocated_size(classPointer);

	int index = bin_search(classPointer, 0, allocated_size - 1, title);

	if (index == -1) {

		cout << " data is not found by the search " << index << endl;

	}

	else {

		cout << " data is found at index " << index << endl;

		cout << classPointer[index]->title << "\t" << classPointer[index]->units << "\t" << classPointer[index]->grade << endl;

	}

}

int find_allocated_size(ClassType *classPointer[]) {

	int count = 0;

	for (int i = 0; i< MAX; i++) {

		if (classPointer[i] != NULL) {

			count++;

		}

	}

	return count;

}

void sort(ClassType *classPointer[]) {

	int n = find_allocated_size(classPointer);



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



		for (int j = 0; j < n - i - 1; j++) {



			if (strcmp(classPointer[j]->title, classPointer[j + 1]->title) > 0) {

				ClassType * temp = classPointer[j];

				classPointer[j] = classPointer[j + 1];

				classPointer[j + 1] = temp;

			}

		}

	}

}

int bin_search(ClassType *classPointer[], int l, int r, char title[30])

{

	if (r >= l)

	{

		int mid = l + (r - l) / 2;

		// If the element is present at the middle

		// itself

		if (strcmp(classPointer[mid]->title, title) == 0)

			return mid;

		// If element is smaller than mid, then

		// it can only be present in left subarray

		if (strcmp(classPointer[mid]->title, title) > 0)

			return bin_search(classPointer, l, mid - 1, title);

		// Else the element can only be present

		// in right subarray

		return bin_search(classPointer, mid + 1, r, title);

	}

	// We reach here when element is not

	// present in array

	return -1;

}
void delete_all_classes(ClassType *classPointer[]){ 
for (int i = 0; i< MAX; i++) { 
	if (classPointer[i] != NULL) 
{ 
		free(classPointer[i]); classPointer[i] = NULL; } }
}

int get_points_from_grade(char grade){ 
int points; switch (grade){ 
case 'A':points = 4; break; 
case 'B':points = 3; break; 
case 'C':points = 2; break; 
case 'D':points = 1; break; 
case 'F':points = 0; break; 
default: points = 0; 
} 
return points; 
}

double getGPACalulation(ClassType *classPointer[]) {
	double gpa = 0.0; int sum_of_the_products = 0;
	int total_number_of_units = 0;
	int n = find_allocated_size(classPointer);
	for (int i = 0; i < n; i++) { 
	total_number_of_units += classPointer[i]->units; 
	int points = get_points_from_grade(classPointer[i]->grade); 
	sum_of_the_products += classPointer[i]->units * points;
	}
	if (total_number_of_units != 0) { 
		gpa = sum_of_the_products / double(total_number_of_units);
	} 
	return(gpa);

}

int main() {

	ClassType *classPointer[MAX];

	for (int i = 0; i< MAX; i++) {

		classPointer[i] = NULL;

	}

	int choice;

	do {

		choice = showMenu();

		switch (choice) {

		case 1:

			add(classPointer);

			break;

		case 2:

			edit(classPointer);

			break;

		case 3:

			display_single_Class(classPointer);

			break;

		case 4: list_all_Classes(classPointer);

			break;

		case 5:

			break;

		case 6:



			break;

		case 7:

			cout << "Exiting the Program" << endl;

			break;

		default:

			cout << "Invalid choice" << endl;

		}



	} while (choice != 7);

}
Last edited on
To accept user input which may contain white space:

a. clear the input buffer (throw away the remnants of the previous line) std::istream::ignore()
http://www.cplusplus.com/reference/istream/istream/ignore/

b. use std::istream::getline() to read the new line http://www.cplusplus.com/reference/istream/istream/getline/

For instance, replace line 87 with:
1
2
3
// cin >> title; // line 87
std::cin.ignore( 1000, '\n' ) ;
std::cin.getline( title, sizeof(title) ) ;


You would also need to do this in other places where the title is to be read.



Line 162: cout << title, units, grade; should have generated several warnings.
Should be something like this:
1
2
3
std::cout << classPointer[user_index]->title << ", "
          << classPointer[user_index]->units << ", "
          << classPointer[user_index]->grade << '\n' ;



Finally, do a complete rewrite of the entire program,
using std::string and std::vector instead of c-style arrays and malloc/free.
https://cal-linux.com/tutorials/strings.html
https://cal-linux.com/tutorials/vectors.html
Thank you so much, I was wondering why it wouldn't read. Thanks a bunch.
Also do you know if somethings wrong with my sort function?

It's supposed to sort the classes by their first letter.

I feel it has to do with the index numbers. Any advice?
Use the standard library. Foe example:

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

struct Class {

    // https://cal-linux.com/tutorials/strings.html
	std::string title ;
	int units;
	char grade;
};

void print( const Class& c )
{
    std::cout << "{ " << std::quoted(c.title) << ", "
              << c.units << ", " << c.grade << " }\n" ;
}

// just an example using vectors and strings
// (this function is not called in this snippet)
// https://cal-linux.com/tutorials/vectors.html
void add_from_user_input( std::vector<Class>& classes )
{
    std::string title ;
    std::cin.ignore( 1000, '\n' ) ;
    std::cout << "title? " ;
    std::getline( std::cin, title ) ;

    int units ;
    std::cout << "units? " ;
    std::cin >> units ;

    char grade ;
    std::cout << "grade? " ;
    std::cin >> grade ;

    classes.push_back( { title, units, grade } ) ;
}

// sort the vector of classes on title
void sort( std::vector<Class>& classes )
{
    // http://en.cppreference.com/w/cpp/algorithm/sort
    // http://www.stroustrup.com/C++11FAQ.html#lambda
    std::sort( classes.begin(), classes.end(),
               []( const Class& a, const Class& b ) { return a.title < b.title ; } ) ;
}

// return the position of class with the specific title in the vector
// return -1 if not found (linear search, sequence need not be sorted)
int find( const std::vector<Class>& classes, const std::string& title )
{
    for( int i = 0 ; i < int( classes.size() ) ; ++i )
        if( classes[i].title == title ) return i ; // found, return the position

    return -1 ; // not found
}

int main()
{
    std::vector<Class> classes { { "maths 102", 4, 'A' }, { "cs 204", 2, 'D' },
                                 { "thermo 101", 5, 'C' }, { "eco 114", 3, 'B' } } ;

    sort(classes) ; // sort on title

    for( const auto& c : classes ) print(c) ; // print the sorted list

    for( std::string title : { "maths 102", "phil 305", "thermo 101" } )
    {
        std::cout << "search for title " << std::quoted(title) << " - " ;

        const int pos = find( classes, title ) ;
        if( pos != -1 )
        {
            std::cout << "found at position " << pos << " : " ;
            print( classes[pos] ) ;
        }
        else std::cout << " not found\n" ;
    }
}

http://coliru.stacked-crooked.com/a/38cc05fa4cbd5f53
Could do the same thing but with simpler code? Sorry but we haven't learned this much in my C++ class.
> Could do the same thing but with simpler code?

No. Using the facilities in the standard library is the simplest way of doing this.
Managing resources manually and dealing with c-style arrays is quite a bit more complicated.


> Sorry but we haven't learned this much in my C++ class.

Well, you should be learning about and using vectors and strings much before you start grappling with raw arrays, pointers, dynamic memory allocation and the like.

More information: http://www.cplusplus.com/forum/lounge/183836/#msg899457
Topic archived. No new replies allowed.