Функция, которая читает строку из файла неизвестной длины - PullRequest
1 голос
/ 16 января 2020

Я пытался собрать воедино функцию, которая позволяет мне создать строку из заданного файла неизвестной длины.

То, что предполагается сделать, это установить размер выходной строки до одного символа, затем для каждого символа, кроме EOF, увеличьте размер строки на 1 и добавьте к нему вновь прочитанный символ.

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

1 Ответ

1 голос
/ 16 января 2020

Если вы работаете в POSIX-совместимой системе (любой современной Linux), не пытайтесь изобретать велосипед заново. Просто используйте getline(). Он сделает сложную работу по управлению растущим буфером для вас и вернет подходящую malloc() 'ed строку.


Вы присваиваете результат malloc() / realloc() для s вместо *s. s является чисто локальным по отношению к readstring(), *s является переменной-указателем, на которую указывает s. Передайте адрес указателя в main. Правильный код выглядит следующим образом:

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

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

Без адреса, принимающего & и разыменования указателя *, ваш main() не может знать, где readstring() хранит символы.

Вам также нужно разыменовать двойной указатель при установке символов строки: используйте (*s)[i] вместо s[i], так как s[i] обозначает указатель, а не символ.


Также, попробуйте запустить вашу программу с valgrind, и посмотрите, сможете ли вы узнать из ошибок, которые она вам выдаст. Это отличный инструмент для отладки проблем, связанных с памятью.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...