C program not taking user input [duplicate] - c

This question already has answers here:
How to do scanf for single char in C [duplicate]
(11 answers)
The program doesn't stop on scanf("%c", &ch) line, why? [duplicate]
(2 answers)
Closed 2 years ago.
i am a beginner in C programming. I was learning about the user inputs. The following piece of code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char grade;
printf("Enter you grade: ");
scanf("%c", &grade);
printf("Your grade is %c.", grade);
return 0;
}
does what I intend it to do i.e.
ask for the grade
display the grade
But when I modify the code to the following :
#include <stdio.h>
#include <stdlib.h>
int main()
{
int age;
printf("Enter you age: ");
scanf("%d", &age);
printf("You are %d years old.\n", age);
printf("-----------------------------\n");
double gpa;
printf("Enter your GPA: ");
scanf("%lf", &gpa);
printf("Your GPA is %f. \n", gpa);
printf("-----------------------------\n");
char grade;
printf("Enter you grade: ");
scanf("%c", &grade);
printf("Your grade is %c.", grade);
return 0;
}
it does the following:
asks for the age
displays the age
asks for the gpa
displays gpa
asks for grade
it doesnt display grade.
The output looks like:
Enter you age: 45
You are 45 years old.
-----------------------------
Enter your GPA: 4
Your GPA is 4.000000.
-----------------------------
Enter you grade: Your grade is
.
please suggest me what I am doing wrong.

When you enter your age, this is what is in the input buffer just before the scanf(%d) starts retrieving characters:
45<newline>
The scan(%d) skips any white space in the buffer (there isn't any), reads the 45, but leaves the newline. Then when you enter your GPA, this is what is in the input buffer just before the scanf(%lf) starts retrieving characters:
<newline>4<newline>
The scan(%lf) skips any white space in the buffer (the newline), reads the 4, but again leaves the newline. In other words, the leading newline doesn't matter if your next next scanf also skips whitespace such as moving from the first entry to the second.
But scanf(%c) does not skip white space. It simply reads the next character, which is a newline:
<newline>A<newline>
That's why tour period appears on the following line, it has read a character, but that character was the newline rather than the grade.
Section 7.21.6.2 The fscanf function, in the ISO C11 standard, has this to say on the first step of processing a conversion specifier (my emphasis):
Input white-space characters (as specified by the isspace function) are skipped, unless the specification includes a [, c, or n specifier.
A quick fix would be to manually skip whitespace yourself, something like:
printf("Enter your grade: ");
scanf(" %c", &grade);
printf("Your grade is %c.", grade);
as per that same section of the standard:
A directive composed of white-space character(s) is executed by reading input up to the first non-white-space character (which remains unread), or until no more characters can be read.

Related

Why isn't this simple code waiting for student name (entered by user)? [duplicate]

This question already has answers here:
scanf() leaves the newline character in the buffer
(7 answers)
Closed 1 year ago.
This C code is not waiting for student name. It directly prints total student number. But when I comment out the first printf-scanf statement(or enter number of students:), then code is waiting for the user to enter student name.
#include <stdio.h>
int main()
{
char name[10];
int count;
printf("ENTER NUMBER OF STUDENTS:\n");
scanf("%d", &count);
printf("ENTER STUDENT NAME:\n");
scanf("%[^\n]%*c", &name);
printf("Total_Students: %d\n", count);
printf("NAME: %s\n", name);
return (0);
}
The second scanf is skipped because the newline character is being interpreted from the first scanf.
For instance, if you entered 2 for number of student, what is being entered is 2\n. The first scanf reads the number 2 and leaves the \n in the buffer which is being interpreted by the 2nd scanf.
You can simply add a space in the second scanf to get past this issue
scanf(" %[^\n]%*c", &name);
change the second scanf() argument to %s and it directly makes the last entry as NULL
.

What is the exact work, that the getchar() is doing? [duplicate]

This question already has answers here:
scanf() leaves the newline character in the buffer
(7 answers)
fgets doesn't work after scanf [duplicate]
(7 answers)
Closed 1 year ago.
Here, if I don't use getchar() the output is misbehaving:
What exactly is the getchar() doing here ?
And what is it holding until another input gets invoked ?
And how will the next input be invoked here in this case ?
My code:
//To take 3 students data using stucture which is user defined.
#include<stdio.h>
#include<stdlib.h>
//#include<conio.h>
struct student
{
char reg_number[200];
char name[200];
int marks_obt;
};
int main()
{
struct student stud1,stud2,stud3;
printf("Enter registration number of student 1 : ");
gets(stud1.reg_number);
printf("Enter name of student 1 : ");
gets(stud1.name);
printf("Enter marks of student 1 : ");
scanf("%d",&stud1.marks_obt);
system("cls");
//getchar();
printf("Enter registration number of student 2 : ");
gets(stud2.reg_number);
printf("Enter name of student 2 : ");
gets(stud2.name);
printf("Enter marks of student 2 : ");
scanf("%d",&stud2.marks_obt);
system("cls");
//getchar();
printf("Enter registration number of student 3 : ");
gets(stud3.reg_number);
printf("Enter name of student 3 : ");
gets(stud3.name);
printf("Enter marks of student 3 : ");
scanf("%d",&stud3.marks_obt);
system("cls");
printf("ID of student 1 is %s \n Name of student 1 is %s \n Marks obtained by stdent 1 is %d",stud1.reg_number,stud1.name,stud1.marks_obt);
printf("\n\n");
printf("ID of student 2 is %s \n Name of student 2 is %s \n Marks obtained by stdent 2 is %d",stud2.reg_number,stud2.name,stud2.marks_obt);
printf("\n\n");
printf("ID of student 3 is %s \n Name of student 3 is %s \n Marks obtained by stdent 3 is %d",stud3.reg_number,stud3.name,stud3.marks_obt);
//getch();
}
First of all, never use the gets(). It is deprecated from the C and C++ standards. The safe way would be to apply fgets():
char input[128];
if (fgets(input, sizeof input, stdin) == NULL) {
// Oops... input was incorrectly given, handle the error
return EXIT_FAILURE; // To quit
}
// Removing the trailing newline character
input[strcspn(input, "\n")] = 0;
You're facing an overlap when asking for another input from the user in the next gets() call because you hit the Return key as well when you finish typing with scanf(). A newline key is added at the end.
The getchar() takes the newline, so it is discarded and does the job you expect.
There are already comments and a correct answer that should be enough, but judging by your last comment it seems that you didn't yet understand what's going on.
This line:
scanf("%d",&stud1.marks_obt);
Parses an integer, for that you press Enter, when you do that a \n is added to the stdin buffer, and remains there, it is not parsed by scanf.
After that:
gets(stud2.reg_number);
Will parse that \n character and store it in stud2.reg_number, and the program moves on.
When you use getchar(), it parses the \n and leaves the stdin buffer empty again so the gets has nothing to parse and waits for your input, correcting the problem, it's still a flimsy solution, but it works in this particular case.
Moral of the story, don't mix scanf with gets, fgets at least, since, as stated, gets was removed from the standard in C11. The reason why some compilers still support it is beyond me.

C : when asking for 2 inputs from a user the 2nd question will not prompt an input to be stored in a variable

If I try grade or fullname one at a time I will get the expected result
"Enter your Grade: "
"Your grade is x"
"Enter your full name:"
"Your full name is xxxx xxxx"
If I run below the print out is
Enter your Grade:2
Your grade is 2
Enter your full name: Your full name is
I can't figure out why I am not been prompted for a second input especially as I know it works when tried on its own */
int main()
{
char grade;
printf("Enter your Grade: ");
scanf("%c", &grade);
printf("Your grade is %c \n", grade);
char fullName[20];
printf("Enter your full name: ");
fgets(fullName, 20, stdin); /*2nd argument specify limits of inputs*, 3rd means standard input ie command console */
printf("Your full name is %s \n", fullName);
return 0;
}
scanf("%c"); buffer problem, %c will only eat one character, so or \n will stay in the buffer for the next one to read.
Try this
#include <stdio.h>
#include <stdlib.h>
int main()
{
char grade;
printf("Enter your Grade: ");
scanf("%c", &grade);
getchar(); // here
printf("Your grade is %c \n", grade);
char fullName[20];
printf("Enter your full name: ");
fgets(fullName, 20, stdin); /*2nd argument specify limits of inputs*, 3rd means standard input ie command console */
printf("Your full name is %s \n", fullName);
return 0;
}
use getchar(); to eat the extra character in the buffer.
Don't mix scanf() with fgets() - in this case, the newline present in the buffer, left untouched by scanf() will be fed to fget() and it won't "ask" for any new input.
Better to use fgets() in all the user-inputs.
The problem lies in this line scanf("%c", &grade); Whenever you use scanf() always keep in mind that the enter key will be stored in your buffer. Since enter key was in your buffer, it went right into fullName when fgets(fullName, 20, stdin); is executed. That's way you got your output:
Enter your Grade:2
Your grade is 2
Enter your full name: Your full name is
You can solve the problem by using getchar(); or getch(); right after scanf(); to capture the Enter key and ensures that fullName get the correct input. Another way to solve it is to use fflush(stdin);. They basically do the same thing, but fflush(stdin); clear Enter key from the buffer. Therefore, fflush(stdin); should be used after scanf(); to clear the unwanted Enter key left by scanf();
This is a long one and have a lot to take in, but I hope this information helps :)))

scanf is being skipped in C [duplicate]

This question already has answers here:
scanf() leaves the newline character in the buffer
(7 answers)
Closed 5 years ago.
I tried to run the following program:
int main(){
char a;
char b;
char c;
printf("\nenter a: ");
scanf("%c", &a);
printf("\nenter b: ");
scanf("%c", &b);
printf("\nenter c: ");
scanf("%c", &c);
return 0;
}
upon running the program it prompts you to enter a value for a. once you do, you are prompted to enter a value for b, however you are not allowed to input a value because the program skips the scan and then prompts you again to input a value for c which is not skipped. I can initialize a and c, but not b. and I have no idea why. I read somewhere that using %[^\n] in the scanf, but I tried using it and I don't think I used it correctly because it still wasn't working.
this is the output (with some input examples):
enter a: 1
enter b:
enter c: 1
process returned 0 (0x0)
Instead of "%c", use " %c".
Without the space, scanf does not skip white spaces when the format specifier is %c. That is initially confusing since it will skip white spaces for other format specifiers, such as %d, %f, %s, etc.
When you press enter, that adds a character to the input queue, which is then read into b.
You can either explicitly read a character to ignore it, or you can use (for one alternative) %1s to read a single-character string (which will skip white-space, including the new-line character entered when you press enter.
'\n' becomes the input for variable b after you press enter.
so to take care of this, use getchar() which will take care of '\n'.
int main(){
char a;
char b;
char c;
printf("\nenter a: ");
scanf("%c", &a);
getchar();
printf("\nenter b: ");
scanf("%c", &b);
getchar();
printf("\nenter c: ");
scanf("%c", &c);
return 0;
}

newline characters in scanf

I have written below program which tries to read and print the values of a structure.
I thought that scanf ignores the /n for all kinf of data except for char but when i run the below program and provide the first input as an integer. I dont get the o/p for name variable. Why??
#include <stdio.h>
#include <string.h>
struct employee
{
int empno;
char name[10];
float p_money;
};
int main()
{
struct employee e;
struct employee *ptr;
ptr = &e;
printf("please enter the empno \n");
scanf("%d", &(ptr->empno));
printf("please enter the name \n");
gets(ptr->name);
//scanf("%d", &(ptr->empno));
printf("please enter the money \n");
scanf("%f", &(ptr->p_money));
printf("Roll No: %d\n", ptr->empno);
printf("Name: %s\n", ptr->name);
printf("Money: %f\n", ptr->p_money);
getchar();
return 0;
}
Execution:
please enter the empno
10
please enter the name
please enter the money
100.99
Roll No: 10
Name:
Money: 100.989998
please enter the empno
10jackal
please enter the name
please enter the money
100.99
Roll No: 10
Name: jackal
Money: 100.989998
The problem is not with scanf but gets - use fgets instead.
char * gets ( char * str );
gets - Reads characters from the standard input (stdin) and stores them as a C string into str until a newline character or the end-of-file is reached.
1use fgets instead of gets... gets is bad.
The reason why gets is bad:
gets Reads characters from the standard input until enter (new line is encountered.) is pressed.
In your case, name[10], and you are doing gets(name). gets does not know how big the name is... If you enter 9 character, it is okay.
But what if you enter more than 9 char? gets() continues to write all the char past the memory which doesn't belong to you hence causing "Undefined Behavior"

Resources