如何从stdin读取一行,阻塞直到找到换行符?

Tay*_*mon 30 c io

我试图从命令行的stdin一次读取任意长度的一行.我不确定我是否能够包含GNU readline并且更喜欢使用库函数.

我读过的文档表明它getline应该有效,但在我的实验中它并没有阻止.我的示例程序:

#include <stdio.h>
int main()
{
    char *line = NULL;
    if (getline(&line, NULL, stdin) == -1) {
        printf("No line\n");
    } else {
        printf("%s\n", line);
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

生成No line,这使它不适合接受用户输入.

我该怎么做呢?我知道这应该是微不足道的,但我无法弄明白.

Cyb*_*m0n 54

试试这个补丁

char *line = NULL;
+size_t size;
+if (getline(&line, &size, stdin) == -1) {
-if (getline(&line, 0, stdin) == -1) {
    printf("No line\n");
} else {
Run Code Online (Sandbox Code Playgroud)

  • 我真的很喜欢这个答案中代码的版本控制风格. (48认同)
  • 这解决了它.我意识到自己的错误; 我误读了文档,认为`n`是`size_t`而不是`size_t*`.谢谢! (3认同)
  • 有没有解释为什么这有效?我假设,因为文档说当行是空指针时忽略大小,我也可以将空指针传递给大小. (2认同)
  • @NickMiller:如果line参数指向NULL,则忽略size参数的_input value_。然后将size参数设置为该函数为您分配的缓冲区的大小,这就是为什么它不能为NULL的原因。 (2认同)

LSe*_*rni 5

我已经能够重现"非阻塞"行为getline:

#include <stdio.h>
#include <stdlib.h>

int main()
{
        char    *buffer;
        size_t  n = 1024;
        buffer = malloc(n);
        return getline(&buffer, &n, stdin);
}
Run Code Online (Sandbox Code Playgroud)

getline(&buffer...块.如果我分配NULLbuffer它,它再次阻塞(如公布的那样),并将该行存储在新分配的缓冲区中.

但如果我写

getline(NULL, &n, stdin);
Run Code Online (Sandbox Code Playgroud)

然后getline失败了,似乎没有阻止.也可能是无效n或文件指针可能导致相同的行为.这可能是问题吗?