why i can't input 2nd book title name? - c

When i Compile this program then i can't input book2.title name,
is it fault about using gets funtion then why?
please explain it more ...........................
#include<stdio.h>
#include<string.h>
struct name{
char author[20];
char title[20];
float price;
};
int main()
{
struct name book1,book2;
printf("Enter 1st title name:");
gets(book1.title);
printf("Enter 1st Author name:");
gets(book1.author);
printf("Enter 1st Book price:");
scanf("%f",&book1.price);
printf("\nThe 1st Book Name is %s",book1.title);
printf("\nThe 1st Book Author is %s",book1.author);
printf("\nThe 1st Book Price is %f",book1.price);
printf("\nEnter 2nd title name:");
gets(book2.title);
printf("Enter 2nd Author name:");
gets(book2.author);
printf("Enter 2nd Book price:");
scanf("%f",&book2.price);
printf("\nThe 2nd Book Name is %s",book2.title);
printf("\nThe 2nd Book Author is %s",book2.author);
printf("\nThe 2nd Book Price is %f",book2.title);
return 0;
}

Your code has two problems unrelated to your question:
The use of gets
The use of %f in printf for a string.
However, the behavior leading to your question lies in these two lines:
scanf("%f",&book1.price);
...
gets(book2.title);
Note, when you enter the book1 price (say 12.3) in the terminal, you press enter afterwards. Therefore, the stdin buffer holds the characters 12.3\n. The scanf reads the first few bytes which it can interpret as a float 12.3, leaving the buffer holding \n. Now, when you run gets, it reads the newline, and your 2nd book's title is the blank string "\0".
See this website: https://www.geeksforgeeks.org/problem-with-scanf-when-there-is-fgetsgetsscanf-after-it/
Note: Please, please use fgets/scanf/getline instead of gets. For more information, see the link posted by #RobertS in the comments above.

Related

C - scanf object's arguments

I'm new in C. I'm trying to make an addStudent() function like this:
I'm currently stuck on 2 issues:
No matter what I have entered, the object's name, mid, and final are still empty or zero.
If I change the name parameter to *name, it only takes the first character. ie, if "James" is entered, it only takes "J".
UPDATE: I firstly thought it was scanf's problem, but even when I removed it and initialized the variables, the object std is still empty. I was still wondering what is the correct way to pass arguments to a new object, like this example.
void addStudent(struct Student array[SIZE], int *currentSize){
char name[20];
int mid, final;
printf("Enter name: ");
scanf("%s", name);
printf("Enter midterm grade: ");
scanf("%d", &mid);
printf("Enter final grade: ");
scanf("%d", &final);
struct Student std = {*name, mid, final};
array[0] = std;
++*currentSize;
}
Student structure:
struct Student{
char name[20];
int midterm;
int final;
};
FIXED:
If I directly passed the variables to scanf, everything works fine.
void addStudent(struct Student array[], int *currentSize){
printf("Enter name: ");
scanf("%s", array[*currentSize].name);
printf("Enter midterm grade: ");
scanf("%d", &array[*currentSize].midterm);
printf("Enter final grade: ");
scanf("%d", &array[*currentSize].final);
++*currentSize;
}
%s format specifier with scanf() reads space-delimited input. In other words, it cannot read a "complete" input which contains white-space.
Quoting C11, chapter 7.21.6.2
s
Matches a sequence of non-white-space characters. [....]
You should use fgets() to read the input and then process it.
That said, changing the argument to %s to *name is not correct anyways, as it creates mismatch between the expected (pointer to character array) and the actual (character) - creating undefined behaviour.

Reading in a list

I've to code a program that reads in a list of student's names and ids and sort them based on first name, last name, and id. But there are currently two problem with my code.
#include <stdio.h>
int main() {
char firstName[200][21], lastName[200][51];
unsigned short id[200]; // used short to decrease memory usage
int i;
for (i=0; i<200; ++i) {
printf("Enter first name of student %d: ",i+1);
getchar(); // FIX to consume enter
fgets(firstName[i],21,stdin);
printf("Enter last name of student %d: ",i+1);
fgets(firstName[i],21,stdin);
printf("Enter student number of student %d: ",i+1);
scanf("%hu",&id[i]);
printf("You've entered %s %s with ID %hu",firstName[i],lastName[i],id[i]);
}
// other functions to do after reading in the data is successfully done
}
Reading in the values must be stopped if students reach 200 or if the user enters EOF.
Student's First Name or Last Name might consist of multiple parts (something like "john john" so I used fgets instead of scanf and %s to read in the word which comes after space as well but it fails and only last name is stored.
Could you tell me how to stop the loop with EOF and read in the first and last name correctly? Thanks.
for checking the EOF , you can use function:
feof(FILE*) // if it returns 1 then it is EOF reached.
you can use it like the below snippet :
if (feof(fp) == 1)
break;
and the 2nd problem :
printf("Enter last name of student %d: ",i+1);
fgets(firstName[i],21,stdin); // this is incorrect.
use 'lastname' instead of 'firstname'. It should be like this :
fgets(lastName[i],21,stdin);
in this way you are overwriting the value of firstname

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"

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..

Why this c code is not generating expected output?

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.

Resources