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

383

Содержимое файла file.txt:

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

Где 5 3 - координатная пара. Как обрабатывать эти данные по строкам в С++?

Я могу получить первую строку, но как получить следующую строку файла?

ofstream myfile;
myfile.open ("text.txt");
Теги:
file-io
ofstream

5 ответов

611
Лучший ответ

Сначала сделайте ifstream:

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

Два стандартных метода:

  • Предположим, что каждая строка состоит из двух чисел и токена чтения с помощью токена:

    int a, b;
    while (infile >> a >> b)
    {
        // process pair (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; } // error
    
        // process pair (a,b)
    }
    

Нельзя смешивать (1) и (2), так как разбор маркера не сожрает новые строки, поэтому вы можете получить ложные пустые строки, если вы используете getline() после того, как извлечение на основе токена вы уже до конца строки.

  • 12
    Будет ли решение № 1 работать с запятыми в качестве токена?
  • 1
    @EdwardKarak: я не понимаю, что означает «запятая как знак». Запятые не представляют собой целые числа.
Показать ещё 21 комментарий
122

Используйте ifstream для чтения данных из файла:

std::ifstream input( "filename.ext" );

Если вам действительно нужно читать строки за строкой, сделайте следующее:

for( std::string line; getline( input, line ); )
{
    ...for each line in input...
}

Но вам, вероятно, просто нужно извлечь координатные пары:

int x, y;
input >> x >> y;

Update:

В вашем коде вы используете ofstream myfile;, однако o в ofstream означает output. Если вы хотите прочитать из файла (ввод), используйте ifstream. Если вы хотите как читать, так и писать, используйте fstream.

  • 7
    Ваше решение немного улучшено: ваша переменная строки не видна после чтения файла, в отличие от второго решения Kerrek SB, которое также является хорошим и простым решением.
  • 3
    getline находится в string see , так что не забывайте #include <string>
5

Расширение принятого ответа, если вход:

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();
5

Так как ваши координаты принадлежат друг другу как пары, почему бы не написать для них структуру?

struct CoordinatePair
{
    int x;
    int y;
};

Затем вы можете написать перегруженный оператор извлечения для istreams:

std::istream& operator>>(std::istream& is, CoordinatePair& coordinates)
{
    is >> coordinates.x >> coordinates.y;

    return is;
}

И тогда вы можете прочитать файл координат прямо в вектор:

#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 << "Couldn't open " << filename << " for reading\n";
    }
    // Now you can work with the contents of v
}
  • 1
    Что происходит, когда невозможно прочитать два int токена из потока в operator>> ? Как можно заставить его работать с анализатором обратного отслеживания (т. Е. Когда operator>> не работает, откатить поток до предыдущей позиции, в конце вернуть false или что-то в этом роде)?
  • 0
    Если невозможно прочитать два int токена, тогда поток is будет иметь значение false и цикл чтения прекратится в этой точке. Вы можете обнаружить это в operator>> , проверив возвращаемое значение отдельных операций чтения. Если вы хотите откатить поток, вы должны вызвать is.clear() .
Показать ещё 1 комментарий
-3

с аргументами командной строки:

#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include "print.h"

using namespace std;

int main (int argc, char *argv[]) 
{
    vector<string> list;
    ifstream in_stream;
    string line;
    in_stream.open(argv[1]);

    while(!in_stream.eof())
    {
        in_stream >> line;
        list.push_back(line);
    }
    in_stream.close();
    print(list);
    sort(list.begin(), list.end());
    print(list);
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню