Вопрос по ios::getline()

 
0
 
C++
ava
Чупакабро | 24.09.2013, 11: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;
}


В чем здесь подвох?
Comments (7)
ava
xvr | 24.09.2013, 14:51 #
Цитата (Чупакабро @  24.9.2013,  10:55 findReferencedText)
В чем здесь подвох?

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

для потока взводится флаг ошибки, и все дальнейшие манипуляции с ним игнорируются. Используйте file.clear()
ava
Чупакабро | 24.09.2013, 19:19 #
xvr
Добавил строку

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

, заработало.
Но почему, почему так криво сделано? Какой тогда вообще смысл в параметре _Count?
непонятно..
ava
xvr | 25.09.2013, 16:43 #
Цитата (Чупакабро @  24.9.2013,  19:19 findReferencedText)
Какой тогда вообще смысл в параметре _Count?

Что бы не переполнился буфер. А так как хотели считать строку и не смогли (она банально не влезла), то это ошибка. Вот флаг в потоке и взвелся
ava
Чупакабро | 25.09.2013, 16:58 #
xvr,
спасибо за разъяснения!
ava
EgoBrain | 27.09.2013, 01:35 #
То есть получается getline в любом случае читает до тех пор пока не наткнется на перевод строки, а второй аргумент влияет лишь на возвращаемое значение?? Так чтоле?
ava
xvr | 27.09.2013, 15:29 #
Цитата (EgoBrain @  27.9.2013,  01:35 findReferencedText)
Так чтоле? 

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


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/
ava
bsa | 28.09.2013, 10:24 #
Рекомендую использовать std::string и std::getline. Значительно удобней и проблем меньше.
Please register or login to write.
Firm of day
Вы также можете добавить свою фирму в каталог IT-фирм, и публиковать статьи, новости, вакансии и другую информацию от имени фирмы.
Подробнее
Contributors
advanced
Submit