Reputation: 189
This part of a program confused me when I'm working in an exercise book.
Why do I get the same result when I swap the last if
statement and while getchar()
?
In both cases I get the sentence "Enter the next title."
first. And in both cases I get getchar()
second, waiting for an input with the cursor blinking.
Shouldn't putting the while(getchar()!= '\n'); continue;
First make the program wait for an input before printing puts("Enter the next title.");
?
My understanding that it should be stuck inside while loop until the condition of exit is present, then proceed to the next statement! which is the print
Here the if statement first:
while(count< MAXBKS && s_gets(library[count].title,MAXTITL) != NULL && library[count].title[0] != '\0')
{
puts("Now enter the author.");
s_gets(library[count].author,MAXAUTL);
puts("Now enter the value.");
scanf("%f", &library[count++].value);
if( count < MAXBKS) // 1 //
puts("Enter the next title.");
while(getchar()!= '\n') // 2 //
continue;
}
here the the while(getchar()..
first:
while(count< MAXBKS && s_gets(library[count].title,MAXTITL) != NULL && library[count].title[0] != '\0')
{
puts("Now enter the author.");
s_gets(library[count].author,MAXAUTL);
puts("Now enter the value.");
scanf("%f", &library[count++].value);
while(getchar()!= '\n') // 2 //
continue;
if( count < MAXBKS) // 1 //
puts("Enter the next title.");
}
Here is the entire program for context:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXTITL 40
#define MAXAUTL 40
#define MAXBKS 10
char * s_gets(char * st, int n);
struct book
{
char title[MAXTITL];
char author[MAXAUTL];
float value;
};
int main(void)
{
struct book library[MAXBKS];
int count = 0;
int index, filecount;
FILE *pbooks;
int size = sizeof(struct book);
if ((pbooks = fopen("book.dat", "a+b")) == NULL)
{
fputs("Can't open book.dat file\n", stderr);
exit(1);
}
rewind(pbooks);
while(count< MAXBKS && fread(&library[count],size,1, pbooks) == 1)
{
if (count ==0)
puts("Current contents of book.dat:");
printf("%s by %s: $%.2f\n", library[count].title, library[count].author, library[count].value);
count++;
}
filecount = count;
if(count == MAXBKS)
{
fputs("The book.dat file is full.\n", stderr);
exit(2);
}
puts("Please add new book titles.");
puts("Press [enter] at the start of a line to stop.\n");
while(count< MAXBKS && s_gets(library[count].title,MAXTITL) != NULL && library[count].title[0] != '\0')
{
puts("Now enter the author.");
s_gets(library[count].author,MAXAUTL);
puts("Now enter the value.");
scanf("%f", &library[count++].value);
while(getchar()!= '\n')
continue;
if( count < MAXBKS)
puts("Enter the next title.");
}
if(count>0)
{
puts("Here is a list of your books:");
for(index =0; index < count; index++)
printf("%s by %s: $%.2f\n", library[index].title, library[index].author, library[index].value);
fwrite(&library[filecount],size,1,pbooks);
}
else
puts("No books? Too bad.\n");
puts("Bye.\n");
fclose(pbooks);
return(0);
}
char *s_gets(char *st, int n)
{
char *ret_val;
char *find;
ret_val= fgets(st,n,stdin);
if (ret_val)
{
find = strchr(st, '\n');
if(find)
*find = '\0';
else
while(getchar() != '\n')
continue;
}
return (ret_val);
}
Upvotes: 0
Views: 2916
Reputation: 13570
Shouldn't putting the
while(getchar()!= '\n'); continue;
first make the program wait for an input before printingputs("Enter the next title.");
?
No, while(getchar()!= '\n'); continue;
will clear the input buffer1, it will
not wait for user input. Then it will print the text. The reason why it doesn't
wait for the user to enter something is that you had a scanf
before. If it
matches a float, it will convert that and save in &library[count++].value
,
however the newline will be left in the input buffer. That's why people use this
method of clearing the rest in the input buffer. If it doesn't match anything,
then the whole line will remain in the input buffer.
For this reason it doesn't matter which you execute first, the buffer will be
cleared and your text will be printed. It is the fgets
in the next s_gets()
call which blocks and waits for user input, not the getchar()
.
My understanding that it should be stuck inside while loop until the condition of exit is present, then proceed to the next statement! which is the print
And so it did, you most likely misinterpreted who blocks and waits for the user input.
Some suggestions:
The clearing of the buffer is best done like this:
int c;
while( (c = getchar()) != '\n' && c != EOF);
Also it is better to always check the return value of scanf
. It will return
the number of successfull matches tokens. So if you expect one conversion, then
check that scanf
returns 1. If that's not the case, the input was wrong. You
may decide to clear the buffer and let the user enter retry again.
1Obviously if the first reading code would be the while(getchar() != '\n') continue;
then it would block and wait for user input, because the input buffer will be empty. But in your case, the input buffer is definitively not empty.
Upvotes: 2