Why this c code is not generating expected output? - c

I have written this simple c code in microsoft visual c++ 2010.
#include<stdio.h>
#include<conio.h>
void main()
{
char title[20], artist[30];
int numtrack, price;
char type;
printf("Enter the title of CD \n");
scanf("%s",title);
printf("\nName of the artist \n");
scanf("%s",artist);
printf("\nEnter the type of CD(enter a for album and s for single)\n");
scanf("%c",&type);
printf("\n Enter the number of tracks \n");
scanf("%d", &numtrack);
printf("\n Enter the price of the cd \n");
scanf("%d", &price);
printf("%s\n%s\n%c\n%d\n%d\n",title, artist, type, numtrack, price);
getch();
}
It's out put is
Enter the title of CD
ranjit
Name of the artist
mahanti
Enter the type of CD(enter a for album and s for single)
Enter the number of tracks
4
Enter the price of the cd
4
ranjit
mahanti
4
4
I can't understand why it is not waiting for input for type variable? Can anybody explain this please? Thanks in advance.

Instead of
scanf("%c",&type);
you want
scanf(" %c",&type);
Otherwise, one of the newline characters from the previous string is going to be consumed as the type.

When you use scanf to read in a string, it reads in only a single word. This single word excludes the newline ("\n") character. When you follow this by scanf to read a single character as you're doing with type, the newline character will be the character that's read.
You can fix this by adding a space before the %c which will ignore any whitespace (see http://www.cplusplus.com/reference/clibrary/cstdio/scanf/): scanf(" %c",&type)

The '\n' from the previous scanf is being processed for type

Add a getchar() after scanf("%s",artist); so that the extra \n (or \r\n) gets consumed.

Related

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.

How to prompt the user to enter an integer and a character from the keyboard in C [duplicate]

This question already has an answer here:
How to read / parse input in C? The FAQ
(1 answer)
Closed 4 years ago.
I am trying to figure out the best way to get an integer and a character from a user
Here is what I have so far:
#include <stdio.h>
int main()
{
int a;
char b;
printf("enter the first number: \n");
scanf("%d", &a);
printf("enter the second char: \n");
scanf("%c", &b);
printf("Number %d",a);
printf("Char %c",b);
return 0;
}
The output is not shown correctly. Is there any problem with this?
Your input and output statements are fine. Just replace printf("Number %d",a); with printf("Number %d\n",a); to better format the output. Also you should change your second scanf statement to scanf(" %c", &b);. This will deal with the newline character entered after the number is inputted.
After you enter the number, you pressed the Enter key. Since the scanf function works on the input stream, when you try to process the next char after reading the number, you are not reading the character you typed, but the '\n' character preceding that. (i.e. because the Enter key you pressed added a '\n' character to your input stream, before you typed your char)
You should change your second call to scanf with the following.
scanf(" %c", &b);
Notice the added space character in the formatting string. That initial space in the formatting string helps skip any whitespace in between.
Additionally, you may want to add \n at the end of the formatting strings of both printf calls you make, to have a better output formatting.
Here you need to take care of hidden character '\n' , by providing the space before the %c in scanf() function , so the "STDIN" buffer will get cleared and scanf will wait for new character in "STDIN" buffer .
modify this statement in your program : scanf("%c",&b); to scanf(" %c",&b);

how to use scanf to get input to include space

I am new to C this is something I have always been confused about
let's say I have a code like this
I only want to use char
char a, b, c;
printf("input first character: ");
scanf(" %c", &a);
printf("input second character: ");
scanf(" %c", &b);
printf("input thrid character: ");
scanf(" %c", &c);
how ever I want to be able to read in space as well; I noticed how this would only read in non-space characters, what if I want to read space as well something like this c=' '; how do I scan this space in;
now by listening to suggestion of using getchar() I wrote this :
#include<stdio.h>
int main(void)
{
char a,b,c;
printf("input the first char:");
a=getchar();
printf("input the second char:");
b=getchar();
printf("input the third char:");
c=getchar();
return 0;
}
how ever something strange happens when I compile and run the program
the program output is like this
input the first char:
input the second char:input the third char:
now it never let me to input the second char it jumped straight to the third request at the end I was only asked to enter 2 inputs which is very strange because the program clearly asked for 3 in the code.
now here is a program I wrote like this I added what is suggested into the code block
int main(void)
{
int totalHeight=0, floorWidth=0, amountOfStories, amountWindowForTop, amountWindowForMiddle, amountWindowForBottom, windowHeight, middleWindowWidth, topWindowWidth, bottomWindowWidth, minimumHeight, minimumWidth;
int betweenDistanceTop, betweenDistanceMiddle, betweenDistanceBottom, edgeDistanceTop, edgeDistanceBottom, edgeDistanceMiddle;
char topFloorWindowContent, middleFloorWindowContent, bottomFloorWindowContent, windowBorder, floorBorder;
int tempMax, tempValue, tempSideDistance, tempBetweenDistance;
printf("please enter how many stories your building would like to have: ");
scanf("%d",&amountOfStories);
minimumHeight=amountOfStories*6+1;
while((totalHeight<minimumHeight)||((totalHeight%amountOfStories)!=1))
{
printf("please enter the totalHeight (minimum %d): ",minimumHeight);
scanf("%d",&totalHeight);
}
printf("please enter how many window building would have for top floor: ");
scanf("%d",&amountWindowForTop);
printf("please enter how many window building would have for middle floors: ");
scanf("%d",&amountWindowForMiddle);
printf("please enter how many window building would have for bottom floor: ");
scanf("%d",&amountWindowForBottom);
tempMax=amountWindowForTop;
if (tempMax<amountWindowForMiddle)
{
tempMax=amountWindowForMiddle;
}
if (tempMax<amountWindowForBottom)
{
tempMax=amountWindowForBottom;
}
while(floorWidth<tempMax)
{
printf("please enter the width of the building (Minimum %d): ",tempMax*4+1);
scanf("%d",&floorWidth);
}
char a, b, c;
printf("a:");
a=getchar();getchar();
printf("b:");
b=getchar();getchar();
printf("c:");
c=getchar();
printf("a=%c, b=%c, c=%c", a, b, c);
return 0;
}
now here is the funny part if I put this block of code in the big program it doesn't work the output is something like this
please enter how many stories your building would like to have: 2
please enter the totalHeight (minimum 13): 2
please enter the totalHeight (minimum 13): 2
please enter the totalHeight (minimum 13): 13
please enter how many window building would have for top floor: 2
please enter how many window building would have for middle floors: 2
please enter how many window building would have for bottom floor: 2
please enter the width of the building (Minimum 9): 9
a:
b:*
c:a=
, b=
, c=
as we can see a b c all read in \n instead of the space * and c didn't even read anything at all Why is that ?
The problem with your code is this: when you read the first char (a), you press enter (\n) for insert the next char, so now on stdin there is a \n that you haven't readed. When you try to read the next character, (b) the program read the previous \n from stdin and does not allow you to read the next char. So, when you read a char with getchar() and then press enter on the keyboard, you need a second getchar() for remove the \n.
Here is a sample code that could solve your issue:
#include<stdio.h>
int main(void) {
char a, b, c;
printf("a:");
a=getchar();getchar();
printf("b:");
b=getchar();getchar();
printf("c:");
c=getchar();
printf("a=%c, b=%c, c=%c", a, b, c);
return 0;
}
For the edited you posted, you need to put what is called "the stdin cleaner" before taking the value for a,b,c:
while(getchar()!='\n');
it just reomove all characters till \n.
Please, take note that when programs like the one you posted has a lot of input from keyboard, sometime you get this issue because there are extra chars in stdin. So the general answer for this issue will be try to figure out where these extra chars (mostly there is an extra \n somewhere) could be and use a function like the one i mentioned to remove so that you can continue reading from stdin.
You should use getchar()
a = getchar();
scanf will not scan anything until you give any data so it is not useful to scan ' ' char.
for this you have to use getchar() fun for char or gets() for string, it will scan data until you give enter. it will comes out even if either you have not provided any char, or simple ' ' char.
If u want to read the character with space then you may use the gets() functtion.
char str[10];
str=gets();
try scanf("%c", &ch).
as stated in scanf format specifier:
"Whitespace character: the function will read and ignore any whitespace characters encountered before the next non-whitespace character (whitespace characters include spaces, newline and tab characters -- see isspace). A single whitespace in the format string validates any quantity of whitespace characters extracted from the stream (including none)."
getchar() gets unexpected result because in windows, newline(when you hit Enter in console) is two characters.

Why gets() function skips when preceded by scanf("%d")?

I want to make a program which take Roll No and Full name as input and simply display it
My code is . this code skip scaning value of n through gets function. Why this error occur and how to over come this?
#include<stdio.h>
#include<conio.h>
void main()
{
int r;
char n[30];
printf("enter your roll no");
scanf("%d",&r);
printf("enter your full name");
gets(n);
printf("roll no is %d ",r);
printf("name is %s ",n);
getch();
}
while the below code scan the first gets value and skips the second one.
#include<stdio.h>
#include<conio.h>
void main()
{
int r;
char n[30], f[30];
printf("enter your roll no");
scanf("%d",&r);
printf("enter your full name");
gets(n);
printf("enter your full name of your father ");
gets(f);
printf("roll no is %d ",r);
printf("name is %s ",n);
printf("father name is %s ",f);
getch();
}
The code DOES NOT skip scanning the value of 'n'.
I believe that when you run the program, you enter the Roll No and then press the ENTER key on your keyboard.
This is the cause.
As soon as you press the ENTER key, the escape sequence '\n' is saved in the array n. Your gets() command is executing perfectly.
In the second case, the variable 'n' stores the escape sequence and the next variable 'f' takes the string you enter next.
To make your code work just enter your scanf statement like this:-
scanf("%d ",&r);
Notice the space after %d.
Try this code-
#include<stdio.h>
int main(void)
{
int r;
char n[30], f[30];
printf("Enter your roll no");
scanf("%d ",&r); // I have inserted a space after %d
printf("Enter your full name");
gets(n);
printf("Enter your full name of your father ");
gets(f);
printf("\nRoll no is %d ",r);
printf("\nName is %s ",n);
printf("\nFather name is %s ",f);
return 0;
}
TIP:- You must try not to use gets() and puts()
You can read more about it here.
The simple solution for the problem is to add fflush(stdin); between scanf(); and gets();
#include<stdio.h>
#include<conio.h>
void main()
{
int r;
char n[30],fn[30];
clrscr();
printf("\nEnter roll ");
scanf("%d",&r);
fflush(stdin);
printf("\nEnter name ");
gets(n);
printf("\nEnter father name ");
gets(fn);
printf("\n\nRoll %d",r);
printf("\nname %s",n);
printf("\nfather name %s",fn);
getch();
}
Using scanf instead of gets will solve your problem:
scanf("%s", n); // Read in your name
Please note that when reading in any string like this you should use safe functions that are passed the length of the string (for example scanf_s from MSDN).
I don't know why it gets skipped but what you could do to avoid any other confusion like fflush(stdin) or fgets etc etc.
Just use gets(string) on the next line. So when it skips the first gets command it goes onto the other one.
Try that
Cheers,
;)
I just had the same problem two hours ago, but to solve this situation easily, all you have to fo is to add a "getchar()" after the "scanf()" and before the "gets()", so that the extra "\n" goes to the "getchar()" and you can type as you want in the next "gets()".
I was also facing the same problem as mentioned above.. so with the help of the answers mentioned here and using hit and trial method, I found that when we press enter after giving input to any variable using scanf(), \n is stored in the next gets() function.. and next time it doesn't take any input from the keyboard.. so to avoid this just use getchar() in between the scanf() nd gets() nd also remember that getchar() takes only 1 character.. so don't give any extra input to scanf() as again this will be stored and will be used in gets() nd the problem will remain the same....
hope this will help..
thank u..

C Programming data input error

I'm writing this to get student information (full name, id and gpa for the last 3 trimester, so I used structures and a for loop to plug in the information however, after 1st excution of the for loop (which means at student 2) my 1st and 2nd input are shown on screen together. How could I prevent this from happening in a simple and easy way to understand? ( P.S: I already tried to put getchar(); at the end of the for loop and it worked, however; I'm not supposed to use it 'cause we haven't learnt in class)
The part of the c program where my error happens:
#include <stdio.h>
struct Student {
char name[30];
int id;
float gpa[3];
};
float averageGPA ( struct Student [] );
int main()
{
int i;
float average;
struct Student studentlist[10];
i=0;
for (i; i<10; i++)
{
printf("\nEnter the Student %d full name: ", i+1);
fgets(studentlist[i].name, 30, stdin);
printf("Enter the Student %d ID: ", i+1);
scanf("\n %d", &studentlist[i].id);
printf("Enter the Student %d GPA for the 1st trimester: ", i+1);
scanf("%f", &studentlist[i].gpa[0]);
printf("Enter the Student %d GPA for the 2nd trimester: ", i+1);
scanf("%f", &studentlist[i].gpa[1]);
printf("Enter the Student %d GPA for the 3rd trimester: ", i+1);
scanf("%f", &studentlist[i].gpa[2]);
}
average = averageGPA(studentlist);
printf("\n\nThe average GPA is %.2f", average);
return 0;
}
float averageGPA (struct Student studentlist[])
{
int i;
float total = 0.0, average = 0.0;
for (i=0; i<10; i++)
{
total = studentlist[i].gpa[0] + studentlist[i].gpa[1] + studentlist[i].gpa[2];
}
average = total / 30 ;
return average;
}
Computer output:
Enter the Student 1 full name: mm
Enter the Student 1 ID: 12
Enter the Student 1 GPA for the 1st trimester: 3
Enter the Student 1 GPA for the 2nd trimester: 4
Enter the Student 1 GPA for the 3rd trimester: 3
Enter the Student 2 full name: Enter the Student 2 ID: <<<<< Here is the problem!!
Try eating the newline after the last scanf:
scanf("%f ", &studentlist[i].gpa[2]);
^
This is very much like your getchar solution. It's actually superior to getchar, since it only discards whitespace.
But you have to use getchar() to discard the newline character that is still in the input buffer after your last scanf("%f"), which according to given format converts a float and leave in the buffer all other chars.
If you can't use getchar(), use another fgets() at the end of the loop.. but of course getchar() would be better
Edit for explanation: whenever you type on your keyboard characters go in a input buffer waiting to be processed by your application. getchar() just "consumes" one character from this buffer (returning it), waiting for a valid char if the buffer is empty. scanf("%f") only "consumes" characters resulting in a float. So, when you type "5.12<enter>", scanf reads and removes from buffer "5.12" leaving "<enter>". So the next fgets() already finds a newline in the buffer and returns immediately; that's why you should use getchar(): ignoring its returning value you successfully discard "<enter>" from the buffer. Finally, please note that if in the buffer there is only "<enter>", scanf("%f") discards it (since it cannot be converted in a float) and waits for another input blocking application.
One last note: input stream is buffered by your OS default policy, in the sense that application does not receive any character until you type "<enter>".
Use scanf in following way to read the student name:
scanf(" %[^\n]",studentlist[i].name);
The first space in the format specifier is important. It negates the newline from previous input. The format, by the way, instructs to read until a newline (\n) is encountered.
[Edit: Adding explanation on request]
The format specifier for accepting a string is %s. But it allows you to enter non-whitespace characters only. The alternative way is to specify the characters that are acceptable (or not acceptable, based on the scenario) within square brackets.
Within square brackets, you can specify individual characters, or ranges, or combination of these. To specify characters to be excluded, precede with a caret (^) symbol.
So, %[a-z] would mean any character between a and z (both included) will be accepted
In your case, we need every character other than the newline to be accepted. So we come up with the specifier %[^\n]
You will get more info on these specifiers from the web. Here's one link for convenience: http://beej.us/guide/bgc/output/html/multipage/scanf.html
The space in the beginning actually 'consumes' any preceding white space left over from previous input. You can refer the answer here for a detailed explanation: scanf: "%[^\n]" skips the 2nd input but " %[^\n]" does not. why?
I would just say no to scanf(). Use fgets() for all input fields and convert to numeric with atoi() and atof().

Resources