Модераторы: bsa
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Вопрос по ios::getline(), странный глюк при чтении файла 
:(
    Опции темы
Чупакабро
Дата 24.9.2013, 10:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 220
Регистрация: 27.2.2007

Репутация: нет
Всего: 4



Есть код, который построчно читает текстовый файл и выводит на экран.
Строковый буфер ограничен 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;
}


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

Это сообщение отредактировал(а) Чупакабро - 24.9.2013, 10:55
--------------------
Project Project1.exe raised exception class EAccessViolation with message 'Access violation at address 00459B8B in module 'Project1.exe'. Read of address 0000019C'. Process stopped. Use Step or Run to continue.
PM MAIL   Вверх
xvr
Дата 24.9.2013, 14:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 35
Всего: 223



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

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

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

PM MAIL   Вверх
Чупакабро
Дата 24.9.2013, 19:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 220
Регистрация: 27.2.2007

Репутация: нет
Всего: 4



xvr
Добавил строку
Код

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

, заработало.
Но почему, почему так криво сделано? Какой тогда вообще смысл в параметре _Count?
непонятно..
--------------------
Project Project1.exe raised exception class EAccessViolation with message 'Access violation at address 00459B8B in module 'Project1.exe'. Read of address 0000019C'. Process stopped. Use Step or Run to continue.
PM MAIL   Вверх
xvr
Дата 25.9.2013, 16:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 35
Всего: 223



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

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

PM MAIL   Вверх
Чупакабро
Дата 25.9.2013, 16:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 220
Регистрация: 27.2.2007

Репутация: нет
Всего: 4



xvr, 
спасибо за разъяснения!
--------------------
Project Project1.exe raised exception class EAccessViolation with message 'Access violation at address 00459B8B in module 'Project1.exe'. Read of address 0000019C'. Process stopped. Use Step or Run to continue.
PM MAIL   Вверх
EgoBrain
Дата 27.9.2013, 01:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 537
Регистрация: 23.3.2008
Где: Комната

Репутация: нет
Всего: 2



То есть получается getline в любом случае читает до тех пор пока не наткнется на перевод строки, а второй аргумент влияет лишь на возвращаемое значение?? Так чтоле?
PM MAIL ICQ Skype   Вверх
xvr
Дата 27.9.2013, 15:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 35
Всего: 223



Цитата(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/

PM MAIL   Вверх
bsa
Дата 28.9.2013, 10:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



Рекомендую использовать std::string и std::getline. Значительно удобней и проблем меньше.
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0867 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.