I can't take the input for the name
of the book for the loops i = 2
and i = 3
.
It is getting skipped. The first input for i = 1
is running absolutely fine.
My code:
#include<stdio.h>
typedef struct book
{
char name[100];
float price;
int pages;
}bk;
int main(void)
{
int i;
bk b[100];
// b1, b2, b3;
for(i=1;i<=3;i++)
{
printf("Enter name of book %d: ",i);
gets(b[i].name);
printf("Enter price of book %d: ",i);
scanf("%f",&b[i].price);
printf("Enter pages of book %d:",i);
scanf("%d",&b[i].pages);
}
printf("\nYour inputs are:");
for(i=1;i<=3;i++)
{
printf("\nName of book %d: %s",i,b[i].name);
printf("\nPrice of book %d: %f",i,b[i].price);
printf("\nPages of book %d: %d",i,b[i].pages);
}
return 0;
}
How should I fix this?
The first thing you need to remember is to never use gets
again, more on that here.
The second is to not mix gets
(or rather fgets
, which is what you should use to replace gets
) and scanf
.
The root of your problem is that in the second loop, gets
reads the newline character left in the buffer by the scanf
at the end of the loop, making it seems as though it was skipped, it was not, if you print b[2].name
you'll see that it has a newline character.
Your code should look more like this:
void clear_buffer(){ //helper function to clear buffer when needed
int c;
while((c = getchar()) != '\n' && c != EOF){}
printf("Bad input, try again: ");
}
//...
int main(void)
{
int i;
bk b[100];
for (i = 0; i < 3; i++)
{
printf("Enter name of book %d: ", i);
while(scanf(" %99[^\n]", b[i].name) != 1){ // mind the space before specifer
clear_buffer();
}
printf("Enter price of book %d: ", i);
while(scanf("%f", &b[i].price) != 1){
clear_buffer(); // if the value was not parsed correctly, ask again
}
printf("Enter pages of book %d:", i);
while(scanf("%d", &b[i].pages) != 1){
clear_buffer();
}
}
//...
//rest of the code
}
The code has some improvements:
Using scanf(" %99[^\n]", b[i].name)
makes sure that there will be no buffer overflow, it will read, at most 99 caracters, reserving a space for the null terminator, which is something gets
cannot do, that's why it was removed from the language, though some compiler still support it, I can't immagine why.
I'm checking if the scanf
really parses the values, if not, let's say someone inputs a character instead of a digit, it asks again, instead of entering an infinite loop which is what would happen before.
for (i = 0; i < 3; i++)
makes sure the array is being populated from index 0, the way you have it, it will not use the first element of the array, you'll have to fix the printf
accordingly..