0

First time asking! Trying to work on a menu...

EDIT: Ok, apparently there is a size limit to these questions, so I can't upload the code directly. I WILL however put it on a viewable pastebin. The program I'm working on is in C, it is supposed to allow the user to- #1: Input your initial (With the option for 'Z' to allow the user to exit the program/start the exit track) #2: Input your numeric grade (0-100), whereupon the program gives you a letter grade (or tells you its invalid, if you entered a number outside 0-100), ticks appropriate counters(total students, A students, total grades, etc) #3: boots the user back to the first question so they can repeat as many times as desired, until they trigger the exit track, then it gives them metrics like # of users, average grade, how many 'A' students, etc.) Problems: #1: When they input a valid grade number, like 87, it tells them they got a 'B', but it ALSO triggers the if-statement designed for invalid grades. here's an example: Attention, deviants. Please do not adjust your internets. This is a public service announcement. Problem #2: I can't figure out a way to design the program so that the exit track will trigger properly. Apparently counters that are edited in a loop are only readable while in that loop...so if I send the user -out- of the loop, I can't output all those nice metrics that were being tallied. Problem #3: The very first run (Initial, then grade) will at least get the proper response (not counting the bonus 'invalid grade' response), but all subsequent attempts ignore my input initial. :/ PASTEBIN LINK FOR CODE: https://pastebin.com/djiCHbhj

9th Aug 2017, 11:57 AM
Solyn Schroeder
4 Answers
0
Please understand that I teach C(along with several other languages), so I may seem a little overly critical but it's only intended as constructive criticism. First, let me address your functional issue. It should be noted that when I compiled & ran your code on my own system, aside from having to 'fix' the "scanf_s()" call, I didn't see the same issues to which you elude in your post. I did see a slightly different problem, however, and I think it comes from the same issue that affected you. I believe the problem you're running into is that scanf() is not appropriately ignoring whitespace. To help hint scanf() to ignore whitespace, include a space preceding the format specifier. Example: scanf(" %c", &initial). The following getchar() is fine, but it's effectively rendered useless. Using the fixed scanf() call, run the code both with and without the getchar() call and you should notice no difference. Unfortunately, this only lets me answer with 2,048 characters, so I guess I'll have to create 2 answer posts to get it all in. If someone else could inform me of a more preferable method, that'd be great. I've created a 'fixed' version for you: https://code.sololearn.com/c8wPW2u292xL/#cpp
10th Aug 2017, 4:14 AM
Gerald O'Steen
0
Next, some design suggestions. I realize that your code indicates an introductory level so I'll try to stay within the scope of information I believe you should have learned up to this point, given your usage of the language. 1 - Consider initializing the character to an integer, preferably 0. For this program, you don't need to start off with a value that would otherwise be considered 'valid' input. 2 - All of your 'double' variables can be initialized to the same value at the same time in a single statement: a = b = c = 0. This vastly improves readability and takes up fewer characters in the overall file. 3 - Your 'while' loop should be inverted as a do-while loop. If you consider the operation of this loop, you obviously want to execute it at least once in all cases. As such, a do-while loop would do exactly that and also prevent the usless conditional test of the 'initial' variable on the first run. 4 - 'scanf_s()' is non-standard. It is a Microsoft-specific extension and should generally be avoided, if at all possible. If it can't be avoided(i.e. your instructor demands its use), then it should at least be used consistently. There's no reason to use 'scanf()' for character input and 'scanf_s()' for numeric input when the latter can handle both. 5 - Separate code using whitespace such that different logical operations are separated from each other. This means, simply, an extra line between the 'grade' input and starting your conditional tests and an extra line before printing out what grade an individual student received. It improves readability by a large margin and helps better identify what can be improved. 6 - Test that the grade is valid first. At current, you're testing all possibilities before determining if you have valid input at all. Instead, start with checking that you have valid input and, if so, proceed to do the other checks. Nesting your conditional statements could also work, but testing first either way will greatly improve the general flow of the program. Limits suck
10th Aug 2017, 4:16 AM
Gerald O'Steen
0
7 - Operations that will happen every time, regardless of what grade the student entered, should happen in the main loop body instead of within the conditions. This means you don't have to repeatedly type 'totStu++' inside each condition, for example. 8 - Prefixed increments should never be slower than postfixed increments but they *could* be faster. It would behoove you to know the implications inherent to '++var' vs 'var++' but it's not an absolute necessity. 9 - Consider using '+=' operator to increase the value of the 'totGrade' variable. Example: totGrade += grade. 10 - If you've already tested for valid input, and you're testing 'grade' in a single direction, then there's no point in using range-checking as it's done implicitly. That may not sound very clear; checking if 'grade' is >= 90 is just as good as checking that it's within 90-100 (inclusive) if you've already made sure that it's <= 100. Likewise, you don't need to check that 'grade' is < 90 when you're doing the next test because if it was, the above condition would have been met. The same holds true for all subsequent tests. 11 - Consider not using something that would otherwise be valid input as the loop condition. It's possible that both Zoie and Zane are in the same class and your program would currently only grade one of them. Instead, don't be afraid to choose a character that's not a letter; '.', '!', '0', etc. can all be good loop-escape characters. 12 - You forgot to calculate the average grade. Don't forget to make sure you're not going to accidentally divide by zero first. A lot of us depend on the Internet daily and we can't afford to let a division-by-zero error do something nasty to it. We're depending on you. ;-P Commented 'fixed' version: https://code.sololearn.com/c8wPW2u292xL/#cpp I hope this was helpful. Let me know if you had any additional questions or concerns. Yay! I got it all in with just 3 whole posts! There's gotta be a better way to do this. Brevity is, obviously, not one of my strengths. ;-P
10th Aug 2017, 4:19 AM
Gerald O'Steen
0
:D I appreciate the assistance, nonetheless! I know there's a lot of hate for programming students asking for help on things, but I would like to think folks understand that when I post something like I have, I'm showing that I -am- putting effort in, and not simply asking for a handout. (After all, if all my work were made by someone else, my degree would be meaningless.) That said, I did look at the fixed code and used it as guidance to fix my own. (As for the 'Z' quit condition, I had the same concern, but unfortunately it was part of the assignment, and I would have lost points for changing that parameter :( )
12th Aug 2017, 9:13 PM
Solyn Schroeder