Форум программистов, компьютерный форум, киберфорум
Наши страницы

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

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

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

11.01.2014, 17:44. Просмотров 1279. Ответов 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;
, то читается правильно, что изменяет этот кусок?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
11.01.2014, 17:44
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Построчное чтение из файла, в токором первая строка пустая (C++):

Построчное чтение из файла - C++
Вечер добрый! С с++ только знакомлюсь. Нужно обработать файл. Построчно считываю данные, и обрабатываю их. Но вот ведь какая...

Построчное чтение из файла - C++
Помогите, не могу разобраться с построчным чтением с файла. Т.е. у меня есть текстовый файл в котором множество строк. Мне нежно прочитать...

Построчное чтение файла - C++
Например есть структура struct Record { char * Name; char * LastName; int Age; }; и есть текстовый файл, например: ...

Построчное чтение из файла - C++
Помогите написать программу которая считывает из файла такой структуры; 1 строка 5 7 2 строка ...

Построчное чтение из файла - C++
такая проблема есть фаил в нем записана информация: 10 Петров А.Л. Сон 1991 4 51 Сидоров В.О. Луна 1970 5 ....... мне нужно считать...

Построчное чтение из файла - C++
Помогите пожалуйста, не могу доделать программу, точнее я её сделала но не так как бы мне хотелось. Вот код программы(прога рабочая) ...

11
Tulosba
:)
Эксперт С++
4397 / 3233 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
11.01.2014, 18:24 #2
Что Вам в итоге надо? А то мешанина какая-то в коде.
0
AndrSlav
44 / 44 / 6
Регистрация: 20.12.2013
Сообщений: 267
11.01.2014, 18:33  [ТС] #3
Надо считывать таблицу значений из файла. Хочу переделать в общем случае- если строка без данных (без цифр, но могут быть разделители), то ее нужно пропустить. Для апробации первую строку файла оставил пустой, в результате код in>>ch; приводит к тому, что в переменную d ничего не заносится. Без этого кода d присваивается значение 12, как и надо. Хочу разобраться почему.

Ведь in>>ch; не должно ничего изменять, если Str=''?
0
Tulosba
:)
Эксперт С++
4397 / 3233 / 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 строке, только передавая прочитанную из файла строку.
1
AndrSlav
44 / 44 / 6
Регистрация: 20.12.2013
Сообщений: 267
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, то не меняется?
0
alsav22
5426 / 4821 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
11.01.2014, 21:17 #6
Цитата Сообщение от AndrSlav Посмотреть сообщение
В этом случае
В каком в этом? Как в приведённом коде? А где здесь чтение?

Добавлено через 2 минуты
Цитата Сообщение от AndrSlav Посмотреть сообщение
Почему так происходит?
Данные в потоке кончаются, устанавливается флаг eof (как при чтении из файла).
0
AndrSlav
44 / 44 / 6
Регистрация: 20.12.2013
Сообщений: 267
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
0
alsav22
5426 / 4821 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
11.01.2014, 21:27 #8
Цитата Сообщение от AndrSlav Посмотреть сообщение
Сумбурно написано, резюмируя: почему если в in.str(str); str - типа string, то при чтении всех элементов из строки состояние потока меняется, а если str- массив из char, то не меняется?
Скорее всего, потому, что массив char не полностью заполнен, и при чтении из строкового потока (после считывания нужной информации) в нём остаются ещё данные (муссор), поэтому флаг eof не устанавливается.

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

Добавлено через 10 минут
Я понимаю, что проблема в конце строки. В массиве char идут пробел, табуляция, число 3 и символ окончания строки /n. В string символа /n нет- в этом проблема? Т.е. для нормальной работы поток должен видеть после прочтения последнего элемента /n, иначе нужна clear()?
p.s. мусора нет, разве что после /n.
0
alsav22
5426 / 4821 / 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 минуты
Потоки устроены аналогично, что строковый, что файловый. Представьте, что вместо строкового потока, вы имеете дело с файловым, только файловый подключен к файлу, а строковый - к строке.
1
AndrSlav
44 / 44 / 6
Регистрация: 20.12.2013
Сообщений: 267
11.01.2014, 22:00  [ТС] #11
Спасибо.

Цитата Сообщение от alsav22 Посмотреть сообщение
Потоки устроены аналогично, что строковый, что файловый. Представьте, что вместо строкового потока, вы имеете дело с файловым, только файловый подключен к файлу, а строковый - к строке.
Может быть так удобнее, подумаю. Просто в действительности 4 столбца, а значения берутся только для трех, кроме первого, но это уже детали.
0
alsav22
5426 / 4821 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
11.01.2014, 22:25 #12
Цитата Сообщение от AndrSlav Посмотреть сообщение
Т.е. для нормальной работы поток должен видеть после прочтения последнего элемента /n, иначе нужна clear()?
Цитата Сообщение от alsav22 Посмотреть сообщение
Потоки устроены аналогично, что строковый, что файловый.
Поэтому и чтение из строкового потока организуется так же, как из файлового: цикл, с проверкой достижения eof (или fail). После выхода из цикла - сброс флагов (clear()).
1
11.01.2014, 22:25
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
11.01.2014, 22:25
Привет! Вот еще темы с ответами:

Построчное чтение из текстового файла - C++
Подскажите плз, как считать не только первую строку, но и все последующие в файле? #include &lt;string.h&gt; #include &lt;stdio.h&gt; int...

Построчное чтение файла в стиле С++ - C++
Господа, передо мной стоит задача реализовать чтение из файла в стиле С++. Реализованно следующим способом: fstream f; ...

Построчное чтение из файла в структуру - C++
Всем доброго дня! Есть структура вида struct Product { char code; char name; double price;

Построчное чтение файла в C++ Builder 6 - C++
Есть кусок кода консольного приложения, слова заносим в массив строк (писал в Dev C++) ifstream w(&quot;words.txt&quot;); string wordBase; ...


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

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Опции темы

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