getline, переходящий указанное количество - PullRequest
0 голосов
/ 24 февраля 2012

У меня есть этот код ....

    file_parser::file_parser(string file){
        txtfile.open(file.c_str(), ios::in);
        if (!txtfile.good()){
            string error=err(0," "+file+" not found. Exit code ",1);
            throw file_parse_exception(error);
        }
        while (!txtfile.eof()){
            char str[200];
            txtfile.getline(str, 200);
            string str2=str;
            vfile.push_back(str2);
        }
        txtfile.close();
    }

и проблема в том, что если во входном файле строка длиной более 200 символов зависает, то происходит сбой. Я проверил значение str при сбое, и ему предшествует нулевой символ, затем он пытается вытолкнуть нулевую (не инициализированную) строку на вектор, что вызывает зависание / сбой. Кто-нибудь знает способ обойти это? Я думал, что при использовании getline он усекает массив символов до 199 (+ ноль) символов, но, видимо, этого не происходит. Я в тупике. Дело в том, что я хочу, чтобы каждый pushback имел максимум 200 символов. Я действительно не хочу ВЕСЬ строки, что будет делать 'String Str'. и если строка содержит более 200 символов, она должна прочитать первые 200, а затем перейти к следующей строке.

1 Ответ

1 голос
/ 24 февраля 2012

Замените ваш входной цикл следующим:

    std::string str;
    while (std::getline(txtfile, str)){
        vfile.push_back(str);
    }

Использование ios::eof() в качестве условия цикла почти всегда создает ошибочную программу, как это было здесь. В этом случае использование eof() имеет две проблемы. Во-первых, eof() устанавливается только после чтения не удается, не раньше, но вы проверяете его перед чтением. Во-вторых, eof() не проверяет диапазон других ошибок. Если строка ввода содержит более 200 символов, istream::getline устанавливает failbit, но не eofbit.

<ч /> РЕДАКТИРОВАТЬ : с добавленным требованием ограничения строк ввода до 200 символов, это должно работать:

// untested
std::string str;
while(std::getline(txtfile, str)) {
    if(str.size() > 200)
        str.erase(200, std::string::npos);
    vfile.push_back(str);
}
...