Чтение файла построчно с использованием ifstream в C++
Проблема:
У меня есть файл file.txt
, содержащий следующие данные:
5 3
6 4
7 1
10 5
11 6
12 3
12 4
Каждая строка файла представляет собой пару координат. Я уже умею считывать первую строку, но не знаю, как обработать последующие строки файла с помощью C++.
Вот мой текущий код для открытия файла:
ifstream myfile;
myfile.open("file.txt");
Как мне считывать и обрабатывать данные построчно? Буду признателен за помощь!
5 ответ(ов)
Сначала создайте объект ifstream
:
#include <fstream>
std::ifstream infile("thefile.txt");
Существуют два стандартных метода чтения данных:
Предположим, что каждая строка состоит из двух чисел, и считывайте токен за токеном:
int a, b; while (infile >> a >> b) { // обработка пары (a, b) }
Разбор на основе строк с использованием строковых потоков:
#include <sstream> #include <string> std::string line; while (std::getline(infile, line)) { std::istringstream iss(line); int a, b; if (!(iss >> a >> b)) { break; } // ошибка // обработка пары (a, b) }
Не следует смешивать (1) и (2), так как разбор на основе токенов не отбрасывает символы новой строки, и в результате вы можете получить ложные пустые строки, если после разбора токенов вызвать getline()
, когда вы уже достигли конца строки.
Для чтения данных из файла в C++ можно использовать ifstream
следующим образом:
std::ifstream input("filename.ext");
Если вам действительно нужно читать файл построчно, используйте следующий код:
for (std::string line; getline(input, line); )
{
// Обрабатываем каждую строку из input...
}
Однако, если вам нужно просто извлекать пары координат, можно сделать это проще:
int x, y;
input >> x >> y;
Обновление:
В вашем коде вы используете ofstream myfile;
, но o
в ofstream
означает output
. Если вы хотите читать из файла, используйте ifstream
. Если вам нужно как читать, так и записывать, используйте fstream
.
Вопрос: Поскольку ваши координаты идут парами, почему бы не создать структуру для их представления?
Ответ: Это отличная идея! Создание структуры для хранения пар координат улучшит читаемость и организацию вашего кода. Например, вы можете определить структуру следующим образом:
struct CoordinatePair
{
int x;
int y;
};
Далее вы можете реализовать оператор перегрузки для извлечения из потоков istream
, чтобы удобно считывать координаты:
std::istream& operator>>(std::istream& is, CoordinatePair& coordinates)
{
is >> coordinates.x >> coordinates.y;
return is;
}
Теперь, когда у вас есть структура CoordinatePair
и перегруженный оператор, вы можете считывать данные из файла и сохранять их прямо в вектор следующим образом:
#include <fstream>
#include <iterator>
#include <vector>
int main()
{
char filename[] = "coordinates.txt";
std::vector<CoordinatePair> v;
std::ifstream ifs(filename);
if (ifs) {
std::copy(std::istream_iterator<CoordinatePair>(ifs),
std::istream_iterator<CoordinatePair>(),
std::back_inserter(v));
}
else {
std::cerr << "Не удалось открыть " << filename << " для чтения\n";
}
// Теперь вы можете работать с содержимым вектора v
}
Таким образом, использование структуры для пар координат сделает ваш код более аккуратным и удобным для работы.
В дополнение к принятому ответу, если входные данные выглядят следующим образом:
1,NYC
2,ABQ
...
вы по-прежнему сможете применить ту же логику, как в следующем примере:
#include <fstream>
std::ifstream infile("thefile.txt");
if (infile.is_open()) {
int number;
std::string str;
char c;
while (infile >> number >> c >> str && c == ',')
std::cout << number << " " << str << "\n";
}
infile.close();
Этот код открывает файл thefile.txt
, считывает целое число и строку, разделенные запятой, и выводит их на экран. Убедитесь, что файл существует и доступен для чтения, иначе infile.is_open()
вернет false
, и программа не будет выполняться корректно.
Этот ответ предназначен для Visual Studio 2017 и объясняет, как читать текстовый файл, расположенный относительно вашего скомпилированного консольного приложения.
Сначала разместите ваш текстовый файл (в данном случае test.txt) в папке вашего решения. После компиляции убедитесь, что файл остается в той же папке, что и applicationName.exe.
Путь к папке будет выглядеть примерно так:
C:\Users\"username"\source\repos\"solutionName"\\"solutionName"
Вот пример кода:
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
ifstream inFile;
// открываем файловый поток
inFile.open(".\\test.txt");
// проверяем, успешно ли открылся файл
if (inFile.fail()) {
cerr << "Ошибка при открытии файла" << endl;
inFile.close();
exit(1);
}
string line;
while (getline(inFile, line))
{
cout << line << endl; // выводим строки файла на консоль
}
// закрываем файловый поток
inFile.close();
}
Обратите внимание, что для успешного выполнения кода необходимо, чтобы файл test.txt находился в той же директории, что и скомпилированный файл .exe вашего приложения.
Что такое Правило трёх?
UnicodeDecodeError: Кодек 'charmap' не может декодировать байт X в позиции Y: символ отображается как <неопределённый>
Найти все файлы с расширением .txt в директории на Python
Имеют ли круглые скобки после имени типа значение при использовании new?
Как удалить элемент из std::vector<> по индексу?