char name[20];
printf("What is your name : ");
scanf("%s",name);
char user_grade;
printf("\nEnter your grade");
scanf("%c", user_grade);
switch(user_grade){
case 'A':
printf("%s you have passed the exams with great grade !",name);
break;
case 'B':
printf("%s you have passed the exams with good grades!",name);
break;
case 'C':
printf("%s you have passed the exams with nice grades!",name);
break;
case 'F':
printf("%s sorry you have failed the exam..");
break;
default:
printf("sorry your grade are invalid. retry again by typing valid grades");
break;
}
So the code has to ask the user their name and grade and check if they have passed the exams or not but the code didn't take the grade input and outputs the result
CodePudding user response:
Try scanf(" %c", &user_grade);
Two changes, put a space before %c so it will discard any leading whitespace, and pass the address of a variable with & so the function can change the variable.
scanf expects a pointer for an argument for each item of input. name is a pointer because you declared it as an array (although you're probably getting a compiler warning there).
CodePudding user response:
Mainly the issue is that you passed user_grade in scanf("%c", user_grade); by value. You need to pass it by reference, using &: scanf("%c", &user_grade);
char name[20];, are you sure the name will be under 20 characters long? What if someone entered a name longer than 20 characters?:
scanf("%s",name); will just write it to the array irrespective of the size of the array, and your program will crash. So, use fgets(name, sizeof name, stdin);. But there is an issue here, fgets() also returns the newline character 0x0A/\n, so you need to remove it using name[strcspn(name, "\n")] = '\0';.
A fflush(stdin); after fgets() might be necessary in some situations here.
Next, you need to pass the variable user_grade by reference to scanf(), since it needs to memory address of user_grade to write to it. Use scanf(" %c", &user_grade);.
Here: CREDIT GOES TO @littleadv: to discard leading whitespace use: scanf(" %c", &user_grade);
For all of the printf() calls inside the switch, its best to add a \n to the end of each string to print on screen.
So, your final code would be:
char name[20] = {}; // initialize to be safe
printf("What is your name : ");
if (fgets(name, sizeof name, stdin) == NULL) {
// check for errors
puts("ERROR reading input!");
exit(1);
}
name[strcspn(name, "\n")] = '\0'; // needs <string.h>
char user_grade = '0'; // initialized to 0, maybe not needed; I would be on the safe side
printf("\nEnter your grade: ");
scanf(" %c", &user_grade); // pass by reference using `&`
switch (user_grade) {
case 'A':
printf("%s you have passed the exams with great grade !\n", name);
break;
case 'B':
printf("%s you have passed the exams with good grades!\n", name);
break;
case 'C':
printf("%s you have passed the exams with nice grades!\n", name);
break;
case 'F':
printf("%s sorry you have failed the exam..\n", name);
break;
default:
printf("sorry your grade are invalid. retry again by typing valid grades\n");
break;
}
Also, you could use switch (tolower(user_grade)) { (tolower() from <ctype.h>) to allow user to enter lowercase grades like a and still be accepted.
Edit:
@DavidC.Rankin suggested that I use fgets instead of scanf to avoid \n being left over and causing problems in loops, so here we can use this instead of scanf(" %c", &user_grade);:
char user_grade[1024] = {};
fgets(user_grade, 1024, stdin);
for (int i = 0; i < strlen(user_grade); i ) {
if (user_grade[i] != ' ' && user_grade[i] != '\t') {
// do the switch here
break;
}
}
