1

I'm learning C and I was reading around what is the best way to take in input line by line.

Basically I want to create strings that hold a whole line of input. The question below doesn't answer how I should handle the memory allocation for the string.

How can I scan strings with spaces in them using scanf()?

Should I first detect how much space is needed? How? Should I just realloc every time I need more space?

Please show an example

Input is from a file or from stdin(both will be possible but not at the same time)

Community
  • 1
  • 1
Noel
  • 966
  • 1
  • 9
  • 19

1 Answers1

0

The following repeatedly allocates buffer storage until the input has been read (malloc/realloc checks omitted):

char *myGetLine(FILE *in)
{
    char *buffer= NULL;
    int c, i, j;

    i= 0; j= 0;
    do
    {
        c= fgetc(in);
        if (i==j) {
            j += 1024;
            buffer= realloc(buffer, j);
        }
        if (c==EOF) break;
        buffer[i++]= c;
    } while (1);
    buffer[i]= '\0';
    return buffer;
}
Paul Ogilvie
  • 25,048
  • 4
  • 23
  • 41
  • Why use a separate buffer `buf` and do all that copying? Just store into `buffer` if there is space, or re-allocate and then store seems to make more sense. – unwind Oct 22 '15 at 14:45
  • 1
    Better, but I think you failed to store the incoming character when reallocating. – unwind Oct 22 '15 at 14:49
  • 2
    Getting there, though. :) It might make sense to return the buffer, to make the function usuble as a reusable building block. – unwind Oct 22 '15 at 14:56
  • Also: you don't need the initial malloc. `buff = realloc(NULL, new_size);` works as expected – joop Oct 22 '15 at 14:59
  • @unwind - fixed your comment. Any reason to keep the down vote? – Paul Ogilvie Oct 22 '15 at 17:03
  • @BLUEPIX, think I fixed your bug report. – Paul Ogilvie Oct 22 '15 at 17:03
  • @PaulOgilvie We're not supposed to say, but I never voted you down for this answer. It will break now if given an empty input, since it will terminate a `NULL` buffer. – unwind Oct 23 '15 at 07:06
  • @Unwind, hi; it won't break on empty input; it will always allocate a buffer. It first gets `c`, then checks/allocates the buffer and only then checks for `c==EOF` and breaks if true, so there will always be a buffer to put in the `\0`. – Paul Ogilvie Oct 23 '15 at 13:19
  • @PaulOgilvie True! #fail. – unwind Oct 23 '15 at 13:32