Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Для новичков > Вопрос по ios::getline()


Автор: Чупакабро 24.9.2013, 10:55
Есть код, который построчно читает текстовый файл и выводит на экран.
Строковый буфер ограничен 70 символами.
Строки короче 70 символов читаются нормально.
Но после того, как считывается строка, по размеру более 70 символов (то есть считывается-то 69), дальнейшие вызовы getline() приводят к чтению 0 символов, программа зацикливается.
Код

#include <iostream>
#include <fstream>
using namespace std;

int main()
{
    ifstream file("text.txt");
    if (!file) return 1;
    char str[70];
    while (!file.eof()) {
        file.getline(str, 70);
        int i = file.gcount();
        cout << str << endl;
        cout << i << endl;
        cin >> i;
    }
    file.close();
    char ch;
    cin >> ch;
    return 0;
}


В чем здесь подвох?

Автор: xvr 24.9.2013, 14:51
Цитата(Чупакабро @  24.9.2013,  10:55 Найти цитируемый пост)
В чем здесь подвох?

В том, что после считывания 
Цитата(Чупакабро @  24.9.2013,  10:55 Найти цитируемый пост)
строка, по размеру более 70 символов 

для потока взводится флаг ошибки, и все дальнейшие манипуляции с ним игнорируются. Используйте file.clear()

Автор: Чупакабро 24.9.2013, 19:19
xvr
Добавил строку
Код

if (file.fail()) file.clear();

, заработало.
Но почему, почему так криво сделано? Какой тогда вообще смысл в параметре _Count?
непонятно..

Автор: xvr 25.9.2013, 16:43
Цитата(Чупакабро @  24.9.2013,  19:19 Найти цитируемый пост)
Какой тогда вообще смысл в параметре _Count?

Что бы не переполнился буфер. А так как хотели считать строку и не смогли (она банально не влезла), то это ошибка. Вот флаг в потоке и взвелся

Автор: Чупакабро 25.9.2013, 16:58
xvr, 
спасибо за разъяснения!

Автор: EgoBrain 27.9.2013, 01:35
То есть получается getline в любом случае читает до тех пор пока не наткнется на перевод строки, а второй аргумент влияет лишь на возвращаемое значение?? Так чтоле?

Автор: xvr 27.9.2013, 15:29
Цитата(EgoBrain @  27.9.2013,  01:35 Найти цитируемый пост)
Так чтоле? 

Нет. Она прочтет столько, сколько влезет в буфер, а потов взведет флаг ошибки
Цитата

istream& getline (char* s, streamsize n );
istream& getline (char* s, streamsize n, char delim );

Get line
Extracts characters from the stream as unformatted input and stores them into s as a c-string, until either the extracted character is the delimiting character, or n characters have been written to s (including the terminating null character).

The failbit flag is set if the function extracts no characters, or if the delimiting character is not found once (n-1) characters have already been written to s. 

http://www.cplusplus.com/reference/istream/istream/getline/

Автор: bsa 28.9.2013, 10:24
Рекомендую использовать std::string и std::getline. Значительно удобней и проблем меньше.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)