如何从标准输入中阻塞地读取一行,直到找到换行符?

37

我试图在命令行从标准输入读取任意长度的一行。我不确定是否能够包含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;
}

输出结果为No line,不适合接受用户输入。

我该怎么做?我知道这应该很简单,但我一直没有弄明白。


2
getline()确实会阻塞(我刚在stdin上测试过)。你能发一下示例代码吗? - LSerni
1
可能是如何在C中从控制台读取一行的重复问题。 - Ciro Santilli OurBigBook.com
2个回答

70

试试这个补丁

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

4
解决了。我意识到了我的错误;我错误地阅读了文档,并认为 n 是一个 size_t 而不是 size_t *。谢谢! - Taymon
71
我非常喜欢这个答案中代码的版本控制风格。 - whirlwin
2
这个为什么有效的解释是什么?我认为既然文档说当行是空指针时大小被忽略,那么我也可以将空指针传递给大小。 - Nicholas Miller
2
@NickMiller:如果行参数指向NULL,则忽略大小参数的输入值。然后,该函数为您分配缓冲区并将大小参数设置为缓冲区的大小,因此它不能为NULL。 - mklement0
getline在STDIN中什么时候返回-1? - serge

9

我已经能够复现getline的“非阻塞”行为:

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

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

getline(&buffer...会阻塞。如果我将NULL分配给buffer,它会再次阻塞(如广告所述),并将行存储在新分配的缓冲区中。

但是,如果我写

getline(NULL, &n, stdin);

如果getline失败,它似乎不会阻塞。可能是无效的n或文件指针导致了相同的行为。这可能是问题所在吗?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接