Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
AndrSlav
44 / 44 / 6
Регистрация: 20.12.2013
Сообщений: 259
#1

Построчное чтение из файла, в токором первая строка пустая - C++

11.01.2014, 17:44. Просмотров 1206. Ответов 11
Метки нет (Все метки)

Читаю построчно файл и заношу значения из строк в переменные
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
   istringstream in(ios_base::in | ios_base::out);
   ostream out(in.rdbuf());
   char ch;
   double d;
   string Str;
   ifstream file;
   file.open("qwe.txt");
 
   if(!file.is_open()) throw CErrCantOpenFile("qwe.txt");
 
   std::getline(file, Str);
   out<<Str;
   in>>ch;
   in.str(std::string());
   std::getline(file, Str);
   out<<Str;
   in>>d;
Вопрос вот в чем: если первая строка файла нулевая- без разделителей и др. символов,

файл:
1 строка:
2 строка: 12 33 23

то со 2ой строчки в переменную d не читается правильное число (в Str действительно 2ая строка). Если убрать
C++
1
in>>ch;
, то читается правильно, что изменяет этот кусок?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
11.01.2014, 17:44     Построчное чтение из файла, в токором первая строка пустая
Посмотрите здесь:
C++ Построчное чтение из файла
Построчное чтение из файла C++
C++ Построчное чтение из файла
Построчное чтение файла C++
Построчное чтение из файла C++
C++ Построчное чтение из файла
Построчное чтение файла в C++ Builder 6 C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Tulosba
:)
Эксперт С++
4392 / 3235 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
11.01.2014, 18:24     Построчное чтение из файла, в токором первая строка пустая #2
Что Вам в итоге надо? А то мешанина какая-то в коде.
AndrSlav
44 / 44 / 6
Регистрация: 20.12.2013
Сообщений: 259
11.01.2014, 18:33  [ТС]     Построчное чтение из файла, в токором первая строка пустая #3
Надо считывать таблицу значений из файла. Хочу переделать в общем случае- если строка без данных (без цифр, но могут быть разделители), то ее нужно пропустить. Для апробации первую строку файла оставил пустой, в результате код in>>ch; приводит к тому, что в переменную d ничего не заносится. Без этого кода d присваивается значение 12, как и надо. Хочу разобраться почему.

Ведь in>>ch; не должно ничего изменять, если Str=''?
Tulosba
:)
Эксперт С++
4392 / 3235 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
11.01.2014, 19:08     Построчное чтение из файла, в токором первая строка пустая #4
Цитата Сообщение от AndrSlav Посмотреть сообщение
Ведь in>>ch; не должно ничего изменять, если Str=''?
В данном случае оно изменяет состояние потока. В частности in.good() становится false.
И если хочется потом из него читать имеет смысл добавить in.clear(), чтобы в следующий раз читалось нормально.
P.S. вообще у Вас как-то путано всё реализовано. Смущает связь во 2ой строке, да и out собственно не нужен. Можно инициализировать строковый поток, как в 14 строке, только передавая прочитанную из файла строку.
AndrSlav
44 / 44 / 6
Регистрация: 20.12.2013
Сообщений: 259
11.01.2014, 21:13  [ТС]     Построчное чтение из файла, в токором первая строка пустая #5
Спасибо, заработало, буду разбираться. Код я из интернета давно брал, честно говоря, первые 2 строчки плохо понимаю, но работало и я не стал трогать. А сейчас решил переделать в общем виде, чтобы не задавать количество столбцов и чтобы пустые строки не влияли.

Добавлено через 1 час 37 минут
И еще вопрос, в данном варианте при считывании всех элементов in>>ch; (или попытке считать еще больше) "изменяет состояние потока", действительно, помогает in.clear(). НО. Раньше у меня использовался другой способ доставания строк из файла:
C++
1
2
3
4
  char str[400];
  FILE* f= fopen("qwe.txt", "r");
  fgets(str, 399, f);
  in.str(str);
В этом случае при считывании количества элементов, действительно находящихся в строке, состояние потока не меняется (при попытке считать дольше- меняется). Почему так происходит? Есть разница в том что отправлять в in.str(str);- string или массив из char? Просто последний вариант у меня много где используется (и как-то не замечал, чтобы он работал неправильно), не хочется потом внезапно нарваться на неприятности.

Добавлено через 11 минут
Сумбурно написано, резюмируя: почему если в in.str(str); str - типа string, то при чтении всех элементов из строки состояние потока меняется, а если str- массив из char, то не меняется?
alsav22
5416 / 4812 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
11.01.2014, 21:17     Построчное чтение из файла, в токором первая строка пустая #6
Цитата Сообщение от AndrSlav Посмотреть сообщение
В этом случае
В каком в этом? Как в приведённом коде? А где здесь чтение?

Добавлено через 2 минуты
Цитата Сообщение от AndrSlav Посмотреть сообщение
Почему так происходит?
Данные в потоке кончаются, устанавливается флаг eof (как при чтении из файла).
AndrSlav
44 / 44 / 6
Регистрация: 20.12.2013
Сообщений: 259
11.01.2014, 21:24  [ТС]     Построчное чтение из файла, в токором первая строка пустая #7
В этом случае все в порядке, d=12:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
istringstream in(ios_base::in | ios_base::out);
   char ch;
   double d;
   char str[400];
   FILE* f= fopen("qwe.txt", "r");
 
   fgets(str, 399, f);
   in.str(str);
   in>>d;
   //in.clear();
   fgets(str, 399, f);
   in.str(str);
   in>>d;
   fclose(f);
А вот в этом меняется состояние потока и в d остается значение из первой строчки d=3
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
   istringstream in(ios_base::in | ios_base::out);
   char ch;
   double d;
   string Str;
   ifstream file;
   file.open("qwe.txt");
 
   if(!file.is_open()) throw CErrCantOpenFile("qwe.txt");
 
   std::getline(file, Str);
   in.str(Str);
   in>>d;
   //in.clear();
   std::getline(file, Str);
   in.str(Str);
   in>>d;
файл qwe.txt

3.0
12.0 33.0 23.0
alsav22
5416 / 4812 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
11.01.2014, 21:27     Построчное чтение из файла, в токором первая строка пустая #8
Цитата Сообщение от AndrSlav Посмотреть сообщение
Сумбурно написано, резюмируя: почему если в in.str(str); str - типа string, то при чтении всех элементов из строки состояние потока меняется, а если str- массив из char, то не меняется?
Скорее всего, потому, что массив char не полностью заполнен, и при чтении из строкового потока (после считывания нужной информации) в нём остаются ещё данные (муссор), поэтому флаг eof не устанавливается.

Добавлено через 1 минуту
AndrSlav, вы отладчиком умеете пользоваться?
AndrSlav
44 / 44 / 6
Регистрация: 20.12.2013
Сообщений: 259
11.01.2014, 21:40  [ТС]     Построчное чтение из файла, в токором первая строка пустая #9
Цитата Сообщение от alsav22 Посмотреть сообщение
AndrSlav, вы отладчиком умеете пользоваться?
Я только с помощью breakpoint-ов ошибки ищу, смотрю значения переменных.

Добавлено через 10 минут
Я понимаю, что проблема в конце строки. В массиве char идут пробел, табуляция, число 3 и символ окончания строки /n. В string символа /n нет- в этом проблема? Т.е. для нормальной работы поток должен видеть после прочтения последнего элемента /n, иначе нужна clear()?
p.s. мусора нет, разве что после /n.
alsav22
5416 / 4812 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
11.01.2014, 21:54     Построчное чтение из файла, в токором первая строка пустая #10
Цитата Сообщение от AndrSlav Посмотреть сообщение
В массиве char идут пробел, табуляция, число 3 и символ окончания строки /n.
Откуда там пробел, табуляция. После чтения через gets(), в массиве: 3.0\n\0, дальше мусор. in >> будет читать до первого пробельного символа (в данном случае, до '\n'), поэтому eof не будет считан и поток останется рабочим. Если чтение из файла в string, то в string будет: 3.0, in >> считает число и eof.

Добавлено через 2 минуты
Цитата Сообщение от AndrSlav Посмотреть сообщение
Т.е. для нормальной работы поток должен видеть после прочтения последнего элемента /n, иначе нужна clear()?
Вам тут вообще строковый поток не нужен. Чтение чисел, в данном случае, делается через метод форматируемого чтения: file >> d.

Добавлено через 2 минуты
Потоки устроены аналогично, что строковый, что файловый. Представьте, что вместо строкового потока, вы имеете дело с файловым, только файловый подключен к файлу, а строковый - к строке.
AndrSlav
44 / 44 / 6
Регистрация: 20.12.2013
Сообщений: 259
11.01.2014, 22:00  [ТС]     Построчное чтение из файла, в токором первая строка пустая #11
Спасибо.

Цитата Сообщение от alsav22 Посмотреть сообщение
Потоки устроены аналогично, что строковый, что файловый. Представьте, что вместо строкового потока, вы имеете дело с файловым, только файловый подключен к файлу, а строковый - к строке.
Может быть так удобнее, подумаю. Просто в действительности 4 столбца, а значения берутся только для трех, кроме первого, но это уже детали.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
11.01.2014, 22:25     Построчное чтение из файла, в токором первая строка пустая
Еще ссылки по теме:
C++ Построчное чтение из текстового файла
Построчное чтение файла в стиле С++ C++
C++ Построчное чтение из файла в структуру
Построчное чтение и обработка данных из файла. C++
Построчное чтение из текстового файла .txt C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
alsav22
5416 / 4812 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
11.01.2014, 22:25     Построчное чтение из файла, в токором первая строка пустая #12
Цитата Сообщение от AndrSlav Посмотреть сообщение
Т.е. для нормальной работы поток должен видеть после прочтения последнего элемента /n, иначе нужна clear()?
Цитата Сообщение от alsav22 Посмотреть сообщение
Потоки устроены аналогично, что строковый, что файловый.
Поэтому и чтение из строкового потока организуется так же, как из файлового: цикл, с проверкой достижения eof (или fail). После выхода из цикла - сброс флагов (clear()).
Yandex
Объявления
11.01.2014, 22:25     Построчное чтение из файла, в токором первая строка пустая
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru