37

I'm trying to read one line at a time, of arbitrary length, from stdin at the command line. I'm not sure if I'll be able to include GNU readline and would prefer to use a library function.

The documentation I've read suggests that getline ought to work, but in my experiments it doesn't block. My sample program:

#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;
}

produces No line, which makes it unsuitable for accepting user input.

How do I do this? I know it should be trivial, but I haven't been able to figure it out.

bumbread
  • 460
  • 2
  • 11
Taymon
  • 24,950
  • 9
  • 62
  • 84

2 Answers2

69

Try this patch

char *line = NULL;
+size_t size;
+if (getline(&line, &size, stdin) == -1) {
-if (getline(&line, 0, stdin) == -1) {
    printf("No line\n");
} else {
CyberDem0n
  • 14,545
  • 1
  • 34
  • 24
  • 4
    This solves it. And I realize my mistake; I misread the documentation and thought `n` was a `size_t` instead of `size_t *`. Thank you! – Taymon Sep 03 '12 at 17:54
  • 71
    I really like the version control style of the code in this answer. – whirlwin Sep 03 '12 at 17:58
  • 2
    Is there an explanation to why this works? I assumed since the documentation says that the size is ignored when the line is a null pointer, that I can also pass a null pointer to the size. – Nicholas Miller Nov 01 '14 at 22:37
  • 2
    @NickMiller: It's the _input value_ of the size parameter that's ignored if the line parameter points to NULL. The size parameter is then set to the size of the buffer that the function allocates for you, that's why it mustn't be NULL. – mklement0 Dec 05 '14 at 22:22
  • when does getline return -1, in STDIN – serge Oct 16 '20 at 12:23
9

I have been able to reproduce a "nonblocking" behaviour on 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... blocks. If I assign NULL to buffer, again it blocks (as advertised), and stores the line in a newly allocated buffer.

But if I write

getline(NULL, &n, stdin);

then getline fails, and seems not to block. Probably also an invalid n or file pointer could cause the same behaviour. Might this be the problem?

LSerni
  • 55,617
  • 10
  • 65
  • 107