getchar() 如何在 While 循环中工作?
How does getchar() work in a While loop?
当我在做练习册时,程序的这一部分让我感到困惑。
为什么当我交换最后一个 if
语句和 while getchar()
时得到相同的结果?
在这两种情况下,我都先得到句子 "Enter the next title."
。在这两种情况下,我都得到 getchar()
秒,等待光标闪烁的输入。
不应该把 while(getchar()!= '\n'); continue;
首先让程序在打印之前等待输入 puts("Enter the next title.");
?
我的理解应该是卡在while循环中,直到出现exit条件,再进行下一条语句!这是打印
首先是if语句:
while(count< MAXBKS && s_gets(library[count].title,MAXTITL) != NULL && library[count].title[0] != '[=10=]')
{
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;
}
首先是while(getchar()..
:
while(count< MAXBKS && s_gets(library[count].title,MAXTITL) != NULL && library[count].title[0] != '[=11=]')
{
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.");
}
这是上下文的完整程序:
#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] != '[=12=]')
{
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 = '[=12=]';
else
while(getchar() != '\n')
continue;
}
return (ret_val);
}
Shouldn't putting the while(getchar()!= '\n'); continue;
first make the program wait for an input before printing puts("Enter the next title.");
?
不,while(getchar()!= '\n'); continue;
会清除输入缓冲区1,它会
不等待用户输入。然后它将打印文本。不行的原因
等待用户输入的东西是你之前有一个scanf
。如果它
匹配一个浮点数,它将转换并保存在 &library[count++].value
,
但是换行符将留在输入缓冲区中。这就是为什么人们使用这个
清除输入缓冲区中剩余部分的方法。如果它不匹配任何东西,
那么整行将保留在输入缓冲区中。
因此,先执行哪个并不重要,缓冲区将是
清除,您的文本将被打印。就是下一个fgets
中的s_gets()
调用哪个块并等待用户输入,而不是 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
确实如此,您很可能误解了谁阻止并等待
用户输入。
一些建议:
最好这样清除缓冲区:
int c;
while( (c = getchar()) != '\n' && c != EOF);
此外,最好始终检查 scanf
的 return 值。它将 return
成功匹配令牌的数量。所以如果你期望一次转化,那么
检查 scanf
returns 1. 如果不是这样,则输入错误。你
可能决定清除缓冲区并让用户输入重试。
1显然,如果第一个读取的代码是 while(getchar() != '\n') continue;
那么它会阻塞并等待用户输入,因为输入缓冲区将为空。但在你的情况下,输入缓冲区肯定不是空的。
当我在做练习册时,程序的这一部分让我感到困惑。
为什么当我交换最后一个 if
语句和 while getchar()
时得到相同的结果?
在这两种情况下,我都先得到句子 "Enter the next title."
。在这两种情况下,我都得到 getchar()
秒,等待光标闪烁的输入。
不应该把 while(getchar()!= '\n'); continue;
首先让程序在打印之前等待输入 puts("Enter the next title.");
?
我的理解应该是卡在while循环中,直到出现exit条件,再进行下一条语句!这是打印
首先是if语句:
while(count< MAXBKS && s_gets(library[count].title,MAXTITL) != NULL && library[count].title[0] != '[=10=]')
{
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;
}
首先是while(getchar()..
:
while(count< MAXBKS && s_gets(library[count].title,MAXTITL) != NULL && library[count].title[0] != '[=11=]')
{
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.");
}
这是上下文的完整程序:
#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] != '[=12=]')
{
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 = '[=12=]';
else
while(getchar() != '\n')
continue;
}
return (ret_val);
}
Shouldn't putting the
while(getchar()!= '\n'); continue;
first make the program wait for an input before printingputs("Enter the next title.");
?
不,while(getchar()!= '\n'); continue;
会清除输入缓冲区1,它会
不等待用户输入。然后它将打印文本。不行的原因
等待用户输入的东西是你之前有一个scanf
。如果它
匹配一个浮点数,它将转换并保存在 &library[count++].value
,
但是换行符将留在输入缓冲区中。这就是为什么人们使用这个
清除输入缓冲区中剩余部分的方法。如果它不匹配任何东西,
那么整行将保留在输入缓冲区中。
因此,先执行哪个并不重要,缓冲区将是
清除,您的文本将被打印。就是下一个fgets
中的s_gets()
调用哪个块并等待用户输入,而不是 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
确实如此,您很可能误解了谁阻止并等待 用户输入。
一些建议:
最好这样清除缓冲区:
int c;
while( (c = getchar()) != '\n' && c != EOF);
此外,最好始终检查 scanf
的 return 值。它将 return
成功匹配令牌的数量。所以如果你期望一次转化,那么
检查 scanf
returns 1. 如果不是这样,则输入错误。你
可能决定清除缓冲区并让用户输入重试。
1显然,如果第一个读取的代码是 while(getchar() != '\n') continue;
那么它会阻塞并等待用户输入,因为输入缓冲区将为空。但在你的情况下,输入缓冲区肯定不是空的。