Может ли ifstream извлечь вещественные числа из произвольного текстового файла...
Про "подводные камни" при извлечении из текстового файла числовых значений нужного типа говорилось в этой заметке (про fscanf
на "грязных" файлах),
а также здесь
и в
"частых ошибках" (про локаль). Тем не менее, во всех этих случаях мы использовали классический способ чтения с помощью функции fscanf
из библиотеки <cstdio>
.
Но подобная же проблема возникает и при работе с потоками ввода ifstream
. Пока файл "правильный", например, содержит только вещественные числа и разделители, всё работает отлично, например:
#include <iostream> #include <fstream> using namespace std; void error(char *s, int exitcode) { puts("\n"); puts(s); puts("\nPress Enter to exit..."); fflush(stdin); getchar(); exit(exitcode); } int main() { ifstream F; F.open("data.txt", ios::in); if (!F) error("Can't open file data.txt",1); double a; //основная часть while (!F.eof()) { F >> a; cout << a << " "; //Обработка очередного значения a - здесь } // F.close(); error("OK", 0); }
...и вот такой простейший файл data.txt
для этой программы:
1.5 2 3.5
Стоит нам "замусорить" data.txt
не-числами, как программа "зацикливается" на последнем прочитанном значении нужного типа.
Суть решения - такая же, как по первой ссылке, по крайней мере, более простого кода я придумать не смог (показана только ограниченная строчными комментариями "основная часть"):
//основная часть while (!F.eof()) { if (F >> a) { cout << a << " "; //Обработка очередного значения a - здесь } else { F.clear(); F.ignore(1); } } //
Мы просто пропускаем следующий символ, пока не найдём допустимого числа :) По крайней мере, вот с таким data.txt
программа справилась:
1.5 A=-2.5 I am not a number=3.3, i too!1e10
Выведено следующее:
1.5 -2.5 3.3 1e+10 OK Press Enter to exit...
Решения мощнее, но и сложнее - вектора, алгоритмы и т.п.
Кстати, впечатление, что методы fstream
не реагируют на локаль, по крайней мере, установка
setlocale(LC_ALL, "RUS");
не заставляет программу считать разделителем целой и дробной части запятую вместо точки.
Как узнать, в какую именно "текущую папку" помещать файл data.txt
- тут.
01.12.2016, 00:04 [5115 просмотров]