Search code examples
cstringpointersmallocdouble-pointer

Can't print char** outside of getline() while loop


Trying to read a file from commandline argument with getline() and store into char**, but when I try to access the data inside like using printf(), it prints nothing. Although printf() works fine within the while loop after each getline().

Any help is greatly appreciated!

int main (int argc, char* argv[])
{
    //open file
    FILE *stream = NULL;
    char *line = NULL;
    size_t len = 0;
    ssize_t nread;
    if (argc != 2)
    {
        fprintf(stderr, "Usage: %s <file>\n", argv[0]);
        exit(EXIT_FAILURE);
    }
    stream = fopen(argv[1], "r");
    if (stream == NULL)
    {
        perror("fopen");
        exit(EXIT_FAILURE);
    }

    //read file line by line
    char ** input = NULL;
    int i = 0;
    int j = 0;
    while ((nread = getline(&line, &len, stream)) != -1)
    {
        j++;
        input = (char **)realloc(input, sizeof(char*) * j);
        input[i] = (char *)malloc(sizeof(char) * strlen(line));
        input[i] = line;

        //print each line (PRINTS FINE)
        printf("%s",input[i]);
        i++;
    }

    //print each line outside of while loop (PRINTS NOTHING)
    for (int z = 0; z < j ; z++)
    {
        printf("%s",input[z]);
    }
}

Welcome to try with any .txt file like this

./a.out input.txt

Solution

  • Your problem is not printing. It is in reading and storing.

    1. sizeof(char) * strlen(line) must be sizeof(char) * (strlen(line) + 1) (you did not allocate space for the NULL terminator). In fact, (strlen(line) + 1) will suffice (see the comment by @user3629249), and even (len + 1) (because len holds the length of the read string).

    2. input[i] = line; does not create a copy of a string. You must use strcpy(input[i], line);.

    3. Finally, you must free(line) at the end.