为什么scanf失败但fgets有效?

时间:2017-04-15 10:12:03

标签: c scanf fgets

我要求用户输入是否要退出程序。有两个片段。一个使用scanf()函数读取输入,而第二个使用fgets()函数读取输入。使用scanf(),程序进入无限循环。使用fgets(),程序按预期执行。为什么scanf()失败,fgets()工作?我如何纠正它,以便scanf()可以工作?这是代码:

首先是scanf()

#include <stdio.h>
#include <string.h>

int main(void)
{

    char yesNo[6];

    printf("Enter [quit] to exit the program, or any key to continue");
    scanf("%s", &yesNo[6]);

    while (strcmp(yesNo,"quit\n") != 0)
    {
         printf("Enter [quit] to exit the program, or any to continue");
         scanf("%s", &yesNo[6]);
    }

    return 0;
}

其次是fgets()

#include <stdio.h>
#include <string.h>

int main(void)
{

    char yesNo[6];

    printf("Enter[quit] to exit the program, or any key to continue: ");
    fgets(yesNo, 6, stdin);

    while (strcmp(yesNo,"quit\n") != 0)
    {
         printf("Enter [quit] to exit the program, or any key to continue:");
         fgets(yesNo, 6, stdin);
    }

    return 0;
}

1 个答案:

答案 0 :(得分:2)

您需要牢记的<![CDATA[ { ]]> scanf("%s")之间的区别在于他们输入的方式。

fgets指示%s丢弃所有前导空白字符并读入所有非空白字符,直到空白字符(或scanf)。它将所有非空白字符存储在其对应的参数中,在本例中为EOF,然后将最后一个空白字符留回标准输入流(yesNo)。它还会NUL终止其相应的参数,在本例中为stdin

yesNo读取所有输入,直到换行符(fgets)或读取的最大字符数作为第二个参数减去1(对于NUL终止符'\n'已读取(或直到'\0')并且所有此输入(包括EOF)都存储在其第一个参数\n中,并且它已被NUL终止。

因此,如果您的yesNo输入为scanf("%s", yesNo);,则quit\n将仅包含yesNo,而quit将保留在\n中1}}。由于字符串stdin"quit"不相同,"quit\n"不会返回零,strcmp循环将继续循环。

对于输入为while的{​​{1}},fgets(yesNo, 6, stdin);将保留quit\nyesNo将为空。 quit\n返回零,因为字符串stdinstrcmp都相等,并且执行来自循环。