在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();
}
发布了0 篇原创文章 · 获赞 52 · 访问量 35万+

猜你喜欢

转载自blog.csdn.net/CHCH998/article/details/105651661