csdnceshi68
local-host
采纳率20%
2011-10-23 20:24 阅读 416

在 c + + 中使用 ifstream 逐行读取文件

The contents of file.txt are:

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

Where 5 3 is a coordinate pair. How do I process this data line by line in 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");

转载于:https://stackoverflow.com/questions/7868936/read-file-line-by-line-using-ifstream-in-c

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享

7条回答 默认 最新

  • 已采纳
    csdnceshi60 ℡Wang Yan 2011-10-23 20:34

    First, make an ifstream:

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

    The two standard methods are:

    1. Assume that every line consists of two numbers and read token by token:

      int a, b;
      while (infile >> a >> b)
      {
          // process pair (a,b)
      }
      
    2. Line-based parsing, using string streams:

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

    You shouldn't mix (1) and (2), since the token-based parsing doesn't gobble up newlines, so you may end up with spurious empty lines if you use getline() after token-based extraction got you to the end of a line already.

    点赞 22 评论 复制链接分享
  • weixin_41568183 零零乙 2011-10-23 20:32

    Use ifstream to read data from a file:

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

    If you really need to read line by line, then do this:

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

    But you probably just need to extract coordinate pairs:

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

    Update:

    In your code you use ofstream myfile;, however the o in ofstream stands for output. If you want to read from the file (input) use ifstream. If you want to both read and write use fstream.

    点赞 20 评论 复制链接分享
  • weixin_41568184 叼花硬汉 2018-07-28 14:35

    Reading a file line by line in C++ can be done in some different ways.

    [Fast] Loop with std::getline()

    The simplest approach is to open an std::ifstream and loop using std::getline() calls. 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

    Another possibility is to use the Boost library, but the code gets a bit more verbose. The performance is quite similar to the code above (Loop with 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

    If performance is critical for your software, you may consider using the C language. This code can be 4-5 times faster than the C++ versions above, see benchmark below

    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. Each line of text contains 10 words in average. 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. Last, but not least, each piece of code logs each line with the printf() function for consistency.

    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. The performance of the C code is what makes the benchmark impressive and can be a game changer in terms of speed.

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

    enter image description here

    点赞 5 评论 复制链接分享
  • csdnceshi54 hurriedly% 2017-05-18 09:35

    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 评论 复制链接分享
  • csdnceshi63 elliott.david 2016-08-20 16:58

    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:

    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
    }
    
    点赞 1 评论 复制链接分享
  • csdnceshi50 三生石@ 2012-06-21 21:53

    with command line arguments:

    #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);
    }
    
    点赞 评论 复制链接分享
  • weixin_41568134 MAO-EYE 2018-05-01 20:11

    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();
    
    点赞 评论 复制链接分享

相关推荐