在C ++中使用ifstream逐行讀取文件

本文翻譯自:Read file line by line using ifstream in C++

The contents of file.txt are: file.txt的內容是:

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

Where 5 3 is a coordinate pair. 其中5 3是一個座標對。 How do I process this data line by line in C++? 如何在C ++中逐行處理此數據?

I am able to get the first line, but how do I get the next line of the file? 我可以獲取第一行,但是如何獲取文件的下一行?

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

#1樓

參考:https://stackoom.com/question/X14K/在C-中使用ifstream逐行讀取文件


#2樓

Since your coordinates belong together as pairs, why not write a struct for them? 由於您的座標是成對在一起的,爲什麼不爲它們編寫一個結構?

struct CoordinatePair
{
    int x;
    int y;
};

Then you can write an overloaded extraction operator for istreams: 然後,您可以爲istream編寫一個重載的提取運算符:

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

    return is;
}

And then you can read a file of coordinates straight into a vector like this: 然後,您可以將座標文件直接讀取爲向量,如下所示:

#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
}

#3樓

Expanding on the accepted answer, if the input is: 如果輸入爲:擴展接受的答案:

1,NYC
2,ABQ
...

you will still be able to apply the same logic, like this: 您仍然可以應用相同的邏輯,如下所示:

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

#4樓

Although there is no need to close the file manually but it is good idea to do so if the scope of the file variable is bigger: 儘管不需要手動關閉文件,但是如果文件變量的範圍較大,最好這樣做:

    ifstream infile(szFilePath);

    for (string line = ""; getline(infile, line); )
    {
        //do something with the line
    }

    if(infile.is_open())
        infile.close();

#5樓

Reading a file line by line in C++ can be done in some different ways. 可以通過C ++逐行讀取文件的方式。

[Fast] Loop with std::getline() [快速]使用std :: getline()循環

The simplest approach is to open an std::ifstream and loop using std::getline() calls. 最簡單的方法是打開std :: ifstream並使用std :: getline()調用循環。 The code is clean and easy to understand. 該代碼是乾淨的,易於理解。

#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] Use Boost's file_description_source [快速]使用Boost的file_description_source

Another possibility is to use the Boost library, but the code gets a bit more verbose. 另一種可能性是使用Boost庫,但是代碼變得更加冗長。 The performance is quite similar to the code above (Loop with std::getline()). 性能與上面的代碼(帶有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();
        }
    }
}

[Fastest] Use C code [最快]使用C代碼

If performance is critical for your software, you may consider using the C language. 如果性能對您的軟件至關重要,則可以考慮使用C語言。 This code can be 4-5 times faster than the C++ versions above, see benchmark below 此代碼的速度可以比上述C ++版本快4-5倍,請參見下面的基準測試

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

Benchmark -- Which one is faster? 基準測試-哪一個更快?

I have done some performance benchmarks with the code above and the results are interesting. 我已經使用上面的代碼做了一些性能基準測試,結果很有趣。 I have tested the code with ASCII files that contain 100,000 lines, 1,000,000 lines and 10,000,000 lines of text. 我已經用包含100,000行,1,000,000行和10,000,000行文本的ASCII文件測試了該代碼。 Each line of text contains 10 words in average. 每行文字平均包含10個字。 The program is compiled with -O3 optimization and its output is forwarded to /dev/null in order to remove the logging time variable from the measurement. 該程序使用-O3優化進行編譯,其輸出轉發到/dev/null以便從測量中刪除記錄時間變量。 Last, but not least, each piece of code logs each line with the printf() function for consistency. 最後但並非最不重要的一點是,每段代碼都使用printf()函數記錄了每一行的一致性。

The results show the time (in ms) that each piece of code took to read the files. 結果顯示每段代碼讀取文件所花費的時間(以毫秒爲單位)。

The performance difference between the two C++ approaches is minimal and shouldn't make any difference in practice. 兩種C ++方法之間的性能差異很小,在實踐中不應有任何區別。 The performance of the C code is what makes the benchmark impressive and can be a game changer in terms of speed. C代碼的性能使基準令人印象深刻,並且可以在速度方面改變遊戲規則。

                             10K lines     100K lines     1000K lines
Loop with std::getline()         105ms          894ms          9773ms
Boost code                       106ms          968ms          9561ms
C code                            23ms          243ms          2397ms

在此處輸入圖片說明


#6樓

This answer is for visual studio 2017 and if you want to read from text file which location is relative to your compiled console application. 該答案適用於Visual Studio 2017,並且如果您要從文本文件中讀取相對於已編譯控制檯應用程序而言位置的信息。

first put your textfile (test.txt in this case) into your solution folder. 首先將您的文本文件(在這種情況下爲test.txt)放到解決方案文件夾中。 After compiling keep text file in same folder with applicationName.exe 編譯後,將文本文件與applicationName.exe保留在同一文件夾中

C:\\Users\\"username"\\source\\repos\\"solutionName"\\"solutionName" C:\\ Users \\“用戶名” \\ source \\ repos \\“ solutionName” \\“ solutionName”

#include <iostream>
#include <fstream>

using namespace std;
int main()
{
    ifstream inFile;
    // open the file stream
    inFile.open(".\\test.txt");
    // check if opening a file failed
    if (inFile.fail()) {
        cerr << "Error opeing a file" << endl;
        inFile.close();
        exit(1);
    }
    string line;
    while (getline(inFile, line))
    {
        cout << line << endl;
    }
    // close the file stream
    inFile.close();
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章