Читать файл строка за строкой с помощью ifstream в C++
содержимое файла.txt-это:
5 3
6 4
7 1
10 5
11 6
12 3
12 4
здесь 5 3 - это пара координат.
Как обрабатывать эти данные построчно в C++?
Я могу получить первую строку, но как мне получить следующую строку файла?
ifstream myfile;
myfile.open ("text.txt");
7 ответов:
во-первых, сделать
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()после извлечение на основе токенов уже привело вас к концу строки.
использовать
ifstreamдля чтения данных из файла:std::ifstream input( "filename.ext" );Если вам действительно нужно читать строку за строкой, то сделайте это:
for( std::string line; getline( input, line ); ) { ...for each line in input... }но вам, вероятно, просто нужно извлечь пары координат:
int x, y; input >> x >> y;обновление:
в вашем коде вы используете
ofstream myfile;, однакоoнаofstreamрасшифровывается какoutput. Если вы хотите прочитать из файла (ввода) используйтеifstream. Если вы хотите одновременно читать и писать используйтеfstream.
С вашими координатами принадлежат вместе, как пары, почему бы не написать структуру для них?
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,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();
чтение файла строка за строкой в C++ может быть сделано несколькими различными способами.
[быстрый] цикл с std:: getline ()
самый простой подход-открыть std::ifstream и цикл с помощью вызовов std:: getline (). Код является чистым и простым для понимания.
#include <fstream> std::ifstream file(FILENAME); if (file.is_open()) { std::string line; while (getline(file, line)) { // using printf() in all tests for consistency printf("%s", line.c_str()); } file.close(); }[Fast] используйте Файл_description_source от Boost
другая возможность-использовать библиотеку Boost, но код становится немного более подробным. Производительность очень похожа на код выше (цикл с std:: getline()).
#include <boost/iostreams/device/file_descriptor.hpp> #include <boost/iostreams/stream.hpp> #include <fcntl.h> namespace io = boost::iostreams; void readLineByLineBoost() { int fdr = open(FILENAME, O_RDONLY); if (fdr >= 0) { io::file_descriptor_source fdDevice(fdr, io::file_descriptor_flags::close_handle); io::stream <io::file_descriptor_source> in(fdDevice); if (fdDevice.is_open()) { std::string line; while (std::getline(in, line)) { // using printf() in all tests for consistency printf("%s", line.c_str()); } fdDevice.close(); } } }[самый быстрый] используйте код C
если производительность имеет решающее значение для вашего программного обеспечения, вы можете рассмотреть возможность использования языка C. Этот код может быть в 4-5 раз быстрее, чем версии C++ выше, см. тест ниже
FILE* fp = fopen(FILENAME, "r"); if (fp == NULL) exit(EXIT_FAILURE); char* line = NULL; size_t len = 0; while ((getline(&line, &len, fp)) != -1) { // using printf() in all tests for consistency printf("%s", line); } fclose(fp); if (line) free(line);Тест -- какая из них быстрее?
Я сделал некоторые тесты производительности с кодом выше, и результаты интересны. Я проверил код с помощью файлов ASCII, которые содержат 100 000 строк, 1 000 000 строк и 10 000 000 строк текста. Каждая строка текста содержит в среднем 10 слов. Программа компилируется с помощью
-O3оптимизация и ее вывод перенаправляется в/dev/nullдля удаления переменной времени регистрации из измерения. И последнее, но не менее важное: каждый фрагмент кода записывает каждую строку сprintf()функция для последовательности.результаты показывают время (в МС), которое каждый кусок кода занял для чтения файлов.
производительность разница между двумя подходами C++ минимальна и не должна иметь никакого значения на практике. Производительность кода C - это то, что делает бенчмарк впечатляющим и может быть игровым чейнджером с точки зрения скорости.
10K lines 100K lines 1000K lines Loop with std::getline() 105ms 894ms 9773ms Boost code 106ms 968ms 9561ms C code 23ms 243ms 2397ms
хотя нет необходимости закрывать файл вручную, но это хорошая идея, чтобы сделать так, если область переменной файл больше:
ifstream infile(szFilePath); for (string line = ""; getline(infile, line); ) { //do something with the line } if(infile.is_open()) infile.close();
с аргументами командной строки:
#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); }

Comments