Search code examples
ckr-c

Help with custom getline() function


Can anyone explain to me why this isn't working?

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

char *getline(int lim)
{
    char c;
    int i;
    char *line;
    line = malloc(sizeof(char) * lim);


    i = 0;
    while((c = getchar()) != '\n' && c != EOF && i < lim-1)
    {
        *line = c;
        line++;
        i++;
    }
    *line = '\0';
    printf("%s", line);
    return line;
}

I'm not worried about the return value right now - just the reason as to why printf("%s", line) isn't working.

Thanks!

EDIT: fixed to line = malloc(sizeof(char) * lim); but it is still not working.

Solution: the address of *line was being incremented throughout the function. When it was passed to printf(), *line pointed to '\0' because that's where its adress was incremented to. Using a temprorary pointer that stored the original address allocated by malloc() to *line and then passing that pointer into printf(), allowed for the function to walk up the pointer.


Solution

  • Because you are only allocating enough space for a single character in this line:

    line = malloc(sizeof(char));
    

    And that is getting filled with the \0 before your printf statement.

    I'm guessing you want to change this line to:

    /* Allocate enough room for 'lim' - 1 characters and a trailing \0 */
    line = malloc(sizeof(char) * lim);
    

    Or even better:

    char *line, *tmp;
    tmp = line = malloc(sizeof(char) * lim);
    

    And then use tmp in all of your pointer math, this way line will still point to the start of your string.

    And I know it's early in your development, but you'll want to make sure you free() the memory that you malloc().


    Here is a working version of your function including my suggested changes:

    #include <stdio.h>
    #include <stdlib.h>
    
    char *getline(int lim)
    {
        char c;
        int i;
        char *line, *tmp;
        tmp = line = malloc(sizeof(char) * lim);
    
        i = 0;
        /* NOTE: 'i' is completely redundant as you can use 'tmp',
         * 'line,' and 'lim' to determine if you are going to
         * overflow your buffer */
        while((c = getchar()) != '\n' && c != EOF && i < lim-1)
        {
            *tmp = c;
            tmp++;
            i++;
        }
        *tmp = '\0';
        printf("%s", line);
        return line;
    }