C++: использование ifstream с getline();

Проверить эту программу

ifstream filein("Hey.txt");
filein.getline(line,99);
cout<<line<<endl;
filein.getline(line,99);
cout<<line<<endl;
filein.close();

В файле Hey.txt много символов. Ну больше 1000

Но мой вопрос: почему во второй раз я пытаюсь напечатать строку. Он не получает печать?


person Mohamed Ahmed Nabil    schedule 26.08.2012    source источник


Ответы (4)


Согласно справочнику C++ (здесь), getline устанавливает ios::fail, когда было извлечено количество символов 1. . Вы должны были бы вызвать filein.clear(); между вызовами getline().

person Roman Kutlak    schedule 26.08.2012
comment
Некоторое объяснение вашего ответа было бы здорово. Что такое ios::fail и что происходит :D - person Mohamed Ahmed Nabil; 27.08.2012
comment
Мне нравятся такие люди, как ты, Толкающие меня вперед вот так. Спасибо еще раз - person Mohamed Ahmed Nabil; 27.08.2012
comment
Есть несколько битов, которые отслеживают внутреннее состояние потока, определенного в std::ios_base: goodbit, badbit, failbit, eofbit. Когда установлен какой-либо из «плохих» битов, поток прекращает чтение и оценивается как false (например, используется как условие while). Вот почему Керрек С.Б. предложил использовать цикл while. - person Roman Kutlak; 27.08.2012
comment
Биты влияют только на поток. На самом деле с файлом ничего не происходит. - person Roman Kutlak; 27.08.2012

Идиоматический способ чтения строк из потока таков:

std::ifstream filein("Hey.txt");

for (std::string line; std::getline(filein, line); ) 
{
    std::cout << line << std::endl;
}

Примечания:

  • Нет close(). C++ позаботится об управлении ресурсами за вас, когда используется идиоматически.

  • Используйте бесплатную std::getline, а не функцию-член потока.

person Kerrek SB    schedule 26.08.2012
comment
Это на самом деле не помогает моей проблеме вообще - person Mohamed Ahmed Nabil; 27.08.2012
comment
@MohamedAhmedNabil: вы никогда не проверяете возвращаемое значение ваших операций ввода, поэтому совершенно невозможно сказать, что делает ваша программа. - person Kerrek SB; 27.08.2012
comment
В первый раз, когда я распечатываю строку, она печатает первые 99 символов, но в следующий раз, когда я это делаю, она ничего не печатает. - person Mohamed Ahmed Nabil; 27.08.2012
comment
@MohamedAhmedNabil: см. выше. Если вы не проверите состояние ошибки после getline, нет гарантии, что что-то произойдет. - person Kerrek SB; 27.08.2012
comment
я должен сделать filein.clear() между каждой линией getline, чтобы это работало. Ты знаешь почему? - person Mohamed Ahmed Nabil; 27.08.2012
comment
Проблема в том, что считается сбоем, если в пределах 98 символов нет новой строки и, таким образом, поток переводится в режим сбоя, т. е. устанавливается std::ios_base::failbit. При установке этого бита поток не будет извлекать никаких символов. Как ни странно, он модифицирует массив символов, чтобы сохранить нулевой символ в следующем, т. е. в первом месте. - person Dietmar Kühl; 27.08.2012
comment
Таким образом, это наиболее идиоматический способ обращения с потоком. - person ThePrimeagen; 07.04.2020

Как правильно сказал Kerrek SB, есть 2 возможности: 1) вторая строка - пустая строка 2) второй строки нет, и все более 1000 символов находятся в одной строке, поэтому второй getline нечего получить.

person BigBoss    schedule 26.08.2012
comment
на самом деле, даже если это была одна строка, getline должна продолжаться с того места, где она остановилась - person Mohamed Ahmed Nabil; 27.08.2012

person    schedule
comment
Хотя этот код может решить проблему, включая объяснение того, как и почему это решает проблему, действительно поможет улучшить качество вашего сообщение и, вероятно, приведет к большему количеству голосов. Помните, что вы отвечаете на вопрос для будущих читателей, а не только для того, кто задает сейчас. Пожалуйста, отредактируйте свой ответ, чтобы добавить пояснения и указать, какие ограничения и предположения применяются. - person Adrian Mole; 21.05.2020