没有获得fgets()函数的预期输出

时间:2012-10-05 06:52:25

标签: c blocking fgets

这里简单的代码我没有得到预期的输出。

#include<stdio.h>

int main()
{
   char buf[1024];
   while(1)
   {
      fgets(buf,strlen(buf),stdin);
      printf("%s",buf);
      printf("hello");
   }
}

在上面的代码中,我想要从键盘输入的字符串,然后打印出来,然后你好。 据我所知fgets()是一个阻塞函数,直到我从键盘输入一个字符串并按下ENTER键,它将阻止程序直到那个时间。因此,当我运行它时,我希望如下

$ ./a.out
I input some text here <ENTER>
I input some text here 
hello

但实际上我得到的输出是终端上印有“hello”的无限循环。为什么我的fgets()没有阻止该程序?有什么想法吗?

4 个答案:

答案 0 :(得分:6)

问题是strlen(buf)返回0因为buf [0]恰好是0(不保证)。您应该使用sizeof(buf)代替:

fgets(buf,sizeof(buf),stdin);

答案 1 :(得分:2)

fgets()来电更改为:

fgets(buf,sizeof(buf),stdin)
//        ^^^^^^

在未初始化的strlen()上调用buf将返回谁知道什么。 strlen()有可能返回0fgets()将立即返回。

答案 2 :(得分:2)

那是因为缓冲区的strlen可能为零。你应该使用sizeof代替,它给你数组的大小(1024)而不是它包含的字符串的长度(这里不确定)。

在您的特定情况下,{em> 可能是一个零大小的字符串(*buf == '\0'),因为fgets调用根本没有阻塞。实际上,自标准规定以来它也可以有一个长度:

  

fgets函数最多读取一个小于n指定的字符数   从流指向的流进入s指向的数组。没有额外的   在换行符(保留)或文件结束后读取字符。一个   在读入数组的最后一个字符后立即写入空字符。

实际上,作为尚未初始化的局部变量,buf可能包含任何,因此您不明智地依赖它(如果它不包含根本就是null终结符,你可能会发现自己正在转移核心,因为strlen运行结束了。)

如果您想要一个经过验证的真实输入函数,请参阅here。它具有缓冲区溢出保护,提示,最后删除换行符,并在行长太长的情况下清除行余数。我将复制下面的代码,使这个答案更加独立。

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

#define OK       0
#define NO_INPUT 1
#define TOO_LONG 2
static int getLine (char *prmpt, char *buff, size_t sz) {
    int ch, extra;

    // Get line with buffer overrun protection.
    if (prmpt != NULL) {
        printf ("%s", prmpt);
        fflush (stdout);
    }
    if (fgets (buff, sz, stdin) == NULL)
        return NO_INPUT;

    // If it was too long, there'll be no newline. In that case, we flush
    // to end of line so that excess doesn't affect the next call.
    if (buff[strlen(buff)-1] != '\n') {
        extra = 0;
        while (((ch = getchar()) != '\n') && (ch != EOF))
            extra = 1;
        return (extra == 1) ? TOO_LONG : OK;
    }

    // Otherwise remove newline and give string back to caller.
    buff[strlen(buff)-1] = '\0';
    return OK;
}

答案 3 :(得分:0)

您应该使用sizeof(buf)而不是strlen(buf),如下所示:

 fgets(buf,sizeof(buf),stdin); 

或直接:

 fgets(buf,1024,stdin);