c - getchar() 如何在 While 循环中工作?

标签 c getchar

当我在练习本上时,程序的这一部分让我感到困惑。

为什么当我交换最后一个 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] != '\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;

    }

这里是 while(getchar().. 首先:

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.");
}

这是上下文的整个程序:

#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);
    }

最佳答案

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。如果它 匹配一个 float ,它将转换并保存在&library[count++].value中, 但是换行符将留在输入缓冲区中。这就是为什么人们使用这个 清除输入缓冲区中剩余部分的方法。如果它不匹配任何东西, 然后整行将保留在输入缓冲区中。

因此,无论先执行哪个都无关紧要,缓冲区将是 清除,您的文本将被打印。就是下一个s_gets()中的fgets 调用 which block 并等待用户输入,而不是 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 的返回值。它会返回 成功匹配 token 的数量。所以如果你期望一次转化,那么 检查 scanf 是否返回 1。如果不是这样,则输入错误。你 可能决定清除缓冲区并让用户输入重试。


1显然,如果第一个读取代码是 while(getchar() != '\n') continue; 那么它会阻塞并等待用户输入,因为输入缓冲区将为空。但在您的情况下,输入缓冲区绝对不是空的。

关于c - getchar() 如何在 While 循环中工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48392361/

相关文章:

c++ - Eclipse错误: Unresolved Inclusion

c - 当我输入文本流时,c=getchar 如何使用缓冲区输出文本流?

c++ - c中的冒泡排序和getchar

c - 为什么我需要按两次 Ctrl-D 来标记文件结束?

c - 如何删除C程序中的重复输出?

c - 关于 getch() 输入的查询

c - 使用 gsl 编写 Runge-Kutta ODE 求解器

将 C 转换为 MIPS - 嵌套数组

c - 如何memset指针到指针

C风格: Macros or preprocessor?