Страницы

Поиск по вопросам

вторник, 25 декабря 2018 г.

Как правильно работать со строками неопределенной длины на С?

Как правильнее работать со строками, длина которых заранее неизвестна?
Т.е. допустим есть функция, которая возврвращает какое-то сообщение. Сообщение может быть очен длинным.
char* get_hello() { char buffer[1024000]; memset(buffer, 0, 1024000 * sizeof(char)); ... while(fgets(...) != NULL) { sprintf(buffer, "%s%s", buffer, row); } ... char* result = malloc(sizeof(buffer) + 1); strncpy(buffer, result, sizeof(buffer)); result[strlen(buffer)] = '\0'; return result; }
Что здесь можно улучшить?


Ответ

У вас непонятно, хотите ли вы считывать весь файл или только строку - до первого
. Если это файл, и весь - то лучше запросить его размер, выделить соответствующий буфер и считать все и сразу.
Если это файл непонятной длины (типа stdin) или вам надо остановиться по прочтении
- то я бы выделил память (не в стеке, а сразу в куче - к чему эти лишние пересылки?) некоторой длины (грубо, каких нибудь 256 байт), и начал бы читать с помощью fgets. Ну, если буфера не хватает - увеличивал бы с помощью realloc, причем сразу в 2 раза, чтоб амортизированное количество переносов сделать O(1) и накапливал считанные куски строки в нем.
Примерно так.
Код нужен или реализуете сами? :)
Update: По просьбам трудящихся :) примерный набросок:
char* getString(FILE* f) { int size = 16, // размер буфера curpos = 0; // текущая позиция char * buf = malloc(size); // if (buf == NULL) - все проверки допишите сами while(fgets(buf+curpos,size-curpos,f)) { curpos += strlen(buf + curpos); if (*(buf+curpos-1) == '
') return buf; if (size - curpos < 2) { buf = realloc(buf,size*=2); } } return buf; };

Комментариев нет:

Отправить комментарий