C代码的奇怪行为(fgets函数)

时间:2013-12-17 11:47:39

标签: c cc

在我的C程序中,fgets没有读取任何数据。请参阅以下代码:

#include <stdio.h>
int main()
{
        char string[50];
        int marks,i,n, limit;
        printf("Enter Limit : \n");
        scanf("%d", &limit);
        FILE *fptr; fptr=(fopen("string.txt","w"));
        if(fptr==NULL){
                printf("Error!");
                return 0;
        }
        printf("Enter a string : \n");
        fgets(string, sizeof(string), stdin);
        fwrite(string, 1, sizeof(string), fptr);
        fclose(fptr);
        return 0;
}

输入限制后,程序显示“输入字符串”并退出(输入任何数据之前)。如果我删除scanf("%d", &limit);语句,它可以正常工作。另外,如果在getchar();之上添加fgets语句,它将正常工作。有谁知道这个问题背后的原因?

3 个答案:

答案 0 :(得分:4)

这是因为您在代码中使用了scanf。输入数字作为输入时,按 Enter 键标记输入的结尾,并在输入缓冲区中添加换行符。 scanf所做的是读取数字,但在输入缓冲区中保留换行符(输入键)。然后,当您致电fgets时,它会看到这个单独的换行符并将其读取。

一个非常简单的解决方案是通过在格式代码后面添加一个空格来告诉scanf跳过尾随空格:

scanf("%d ", &limit);
/*       ^         */
/*       |         */
/* Note space here */

如果上述解决方案不起作用,那么您可以读取字符,直到获得换行符:

int c;
while ((c = fgetc(stdin)) != EOF && c != '\n')
    ;

此外,在Mac OSX中有fpurge函数,可用于清除输入流中的未读数据:

fpurge(stdin);

注意: fpurge功能 便携。

在Linux和Windows上,您可以使用fflush执行fpurge所做的相同操作,但请注意,它是允许Linux和Windows的库中的扩展。根据C规范,在输入流上调用fflush是未定义的行为。参见例如the Linux manual pageWindows reference page

答案 1 :(得分:0)

如果您使用sscanf并输入数字,则点击“输入”...数字由sscanf处理,但“输入”由fgets处理

答案 2 :(得分:0)

这是因为fgets会读取前一个\n留下的换行符scanf。吃\n的一种可能方法是在getchar之后添加scanf

    getchar();
    printf("Enter a string : \n");
    fgets(string, sizeof(string), stdin);