3

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

#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

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

4

4 回答 4

6

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

fgets(buf,sizeof(buf),stdin);
于 2012-10-05T06:55:29.630 回答
2

将调用更改fgets()为:

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

调用strlen()未初始化的buf将返回谁知道是什么。有机会strlen()返回0,在这种情况下fgets()将立即返回。

于 2012-10-05T06:54:56.650 回答
2

那是因为strlen你的缓冲区可能为零。您应该sizeof改用它,它为您提供数组的大小(1024),而不是它包含的字符串的长度(此处不确定)。

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

fgets 函数从 stream 指向的流中最多读取比 n 指定的字符数少 1 的字符到 s 指向的数组中。在换行符(保留)之后或文件结尾之后不会读取其他字符。在读入数组的最后一个字符之后立即写入一个空字符。

实际上,作为尚未初始化的局部变量,buf可能包含任何内容,因此您不明智地依赖它(如果它根本不包含空终止符,您甚至可能会发现自己在strlen运行时转储核心结束)。

如果您想要一个久经考验的真实输入功能,请参见此处。它具有缓冲区溢出保护,提示,在末尾删除换行符,并在它太长的情况下清除剩余的行。我将复制下面的代码以使这个答案更加独立。

#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;
}
于 2012-10-05T06:56:21.713 回答
0

您应该像这样使用 sizeof(buf) 而不是 strlen(buf) :

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

或直接:

 fgets(buf,1024,stdin);
于 2012-10-05T07:02:02.253 回答