Страницы

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

вторник, 31 декабря 2019 г.

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

#c


Как правильнее работать со строками, длина которых заранее неизвестна?

Т.е. допустим есть функция, которая возврвращает какое-то сообщение. Сообщение может
быть очен длинным.

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


Что здесь можно улучшить?
    


Ответы

Ответ 1



У вас непонятно, хотите ли вы считывать весь файл или только строку - до первого \n. Если это файл, и весь - то лучше запросить его размер, выделить соответствующий буфер и считать все и сразу. Если это файл непонятной длины (типа stdin) или вам надо остановиться по прочтении \n - то я бы выделил память (не в стеке, а сразу в куче - к чему эти лишние пересылки?) некоторой длины (грубо, каких нибудь 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) == '\n') return buf; if (size - curpos < 2) { buf = realloc(buf,size*=2); } } return buf; };

Ответ 2



FILE * pFile = ... fseek( pFile, 0L, SEEK_SET ); // указатель текущей позиции файла в начале fseek( pFile, 0L, SEEK_END ); // теперь - в самом конце size_t fSize = ftell( pFile ); // `ftell` вернул Вам необходимый для размещения данных размер Стоит только помнить о том, как работает ftell если Вы читаете бинарный поток.

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

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