8

Чтение файла построчно с использованием ifstream в C++

1

Проблема:

У меня есть файл file.txt, содержащий следующие данные:

5 3
6 4
7 1
10 5
11 6
12 3
12 4

Каждая строка файла представляет собой пару координат. Я уже умею считывать первую строку, но не знаю, как обработать последующие строки файла с помощью C++.

Вот мой текущий код для открытия файла:

ifstream myfile;
myfile.open("file.txt");

Как мне считывать и обрабатывать данные построчно? Буду признателен за помощь!

5 ответ(ов)

11

Сначала создайте объект ifstream:

#include <fstream>
std::ifstream infile("thefile.txt");

Существуют два стандартных метода чтения данных:

  1. Предположим, что каждая строка состоит из двух чисел, и считывайте токен за токеном:

    int a, b;
    while (infile >> a >> b)
    {
        // обработка пары (a, b)
    }
    
  2. Разбор на основе строк с использованием строковых потоков:

    #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(), когда вы уже достигли конца строки.

2

Для чтения данных из файла в 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.

0

Вопрос: Поскольку ваши координаты идут парами, почему бы не создать структуру для их представления?

Ответ: Это отличная идея! Создание структуры для хранения пар координат улучшит читаемость и организацию вашего кода. Например, вы можете определить структуру следующим образом:

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
}

Таким образом, использование структуры для пар координат сделает ваш код более аккуратным и удобным для работы.

0

В дополнение к принятому ответу, если входные данные выглядят следующим образом:

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, и программа не будет выполняться корректно.

0

Этот ответ предназначен для 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 вашего приложения.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь