PossiblyIncompetent
PossiblyIncompetent

Reputation: 13

Function that reads a string from a file of unknown length

I've been trying to piece together a function that allows me to create a string out of a given file of unknown length.

What it's supposed to do, is set the size of the output string to a single character, then for each character besides EOF, increment the size of the string by 1 and add the newly read character to it.

void readstring(FILE *f, char *s[])
{
    int size = 1;
    int c = 0, i = 0;

    s = malloc(size*sizeof(char));

    while(c != -1)
    {
        c = fgetc(f);
        s[i] = (char)c;
        i++;

        if(i == size)
        {
            size++;
            s = realloc(s, size*sizeof(char));
        }
    }

    s[i] = '\0';
}

int main()
{
    char *in = malloc(2*sizeof(char));
    FILE *IN;

    IN = fopen("in.txt", "r");

    readstring(IN, in);

    printf("%s",&in);

    fclose(IN);
    free(in);

    return 0;
}

Upvotes: 1

Views: 92

Answers (1)

If you are on a POSIX compliant system (any modern Linux), don't try to reinvent the wheel. Just use getline(). It will do the tricky stuff of managing a growing buffer for you, and return a suitably malloc()'ed string.


You are assigning the result of malloc()/realloc() to s instead of *s. s is purely local to readstring(), *s is the pointer variable that s points to. Pass in the adress of the pointer in main. Correct code looks like this:

void foo(char** out_string) {
    *out_string = malloc(...);
}

int main() {
    char* string;
    foo(&string);
}

Without the address taking & and pointer dereferenciation *, your main() cannot know where readstring() has stored the characters.

You also need to dereference the double pointer when you set the characters of the string: Use (*s)[i] instead of s[i], as s[i] denotes a pointer, not a character.


Also, try running your program with valgrind, and see if you can learn from the errors that it will spew out at you. It's a great tool for debugging memory related problems.

Upvotes: 1

Related Questions