Getting the nth line of a text file in C++

2019-04-25 02:31发布

I need to read the nth line of a text file (e.g. textfile.findline(0) would find the first line of the text file loaded with ifstream textfile). Is this possible? I don't need to put the contents of the file in an array/vector, I need to just assign a specific line of the text file to a varible (specifically a int).

P.S. I am looking for the simplest solution that would not require me to use any big external library (e.g. Boost) Thanks in advance.

5条回答
萌系小妹纸
2楼-- · 2019-04-25 02:45

How about this?

std::string ReadNthLine(const std::string& filename, int N)
{
   std::ifstream in(filename.c_str());

   std::string s;
   //for performance
   s.reserve(some_reasonable_max_line_length);    

   //skip N lines
   for(int i = 0; i < N; ++i)
       std::getline(in, s);

   std::getline(in,s);
   return s; 
}
查看更多
三岁会撩人
3楼-- · 2019-04-25 02:47

If you want to read the start of the nth line, you can use stdin::ignore to skip over the first n-1 lines, then read from the next line to assign to the variable.

template<typename T>
void readNthLine(istream& in, int n, T& value) {
  for (int i = 0; i < n-1; ++i) {
    in.ignore(numeric_limits<streamsize>::max(), '\n');
  }
  in >> value;
}
查看更多
狗以群分
4楼-- · 2019-04-25 02:51

It's certainly possible. There are (n-1) '\n' characters preceding the nth line. Read lines until you reach the one you're looking for. You can do this on the fly without storing anything except the current line being considered.

查看更多
Explosion°爆炸
5楼-- · 2019-04-25 02:58

Armen's solution is the correct answer, but I thought I'd throw out an alternative, based on jweyrich's caching idea. For better or for worse, this reads in the entire file at construction, but only saves the newline positions (doesn't store the entire file, so it plays nice with massive files.) Then you can simply call ReadNthLine, and it will immediately jump to that line, and read in the one line you want. On the other hand, this is only optimal if you want to get only a fraction of the lines at a time, and the line numbers are not known at compile time.

class TextFile {
    std::ifstream file_stream;
    std::vector<std::ifstream::streampos> linebegins;
    TextFile& operator=(TextFile& b) = delete;
public;
    TextFile(std::string filename) 
    :file_stream(filename) 
    {
        //this chunk stolen from Armen's, 
        std::string s;
        //for performance
        s.reserve(some_reasonable_max_line_length); 
        while(file_stream) {
            linebegins.push_back(file_stream.tellg());
            std::getline(file_stream, s);
        }
    }
    TextFile(TextFile&& b) 
    :file_stream(std::move(b.file_stream)), 
    :linebegins(std::move(b.linebegins))
    {}
    TextFile& operator=(TextFile&& b) 
    {
        file_stream = std::move(b.file_stream);
        linebegins = std::move(b.linebegins);
    }
    std::string ReadNthLine(int N) {
        if (N >= linebegins.size()-1)
            throw std::runtime_error("File doesn't have that many lines!");
        std::string s;
        // clear EOF and error flags
        file_stream.clear();
        file_stream.seekg(linebegins[N]);
        std::getline(file_stream, s);
        return s;
    }
};
查看更多
唯我独甜
6楼-- · 2019-04-25 02:58

Here is a working and neat example using std::getline():

#include <iostream>
#include <fstream>
#include <string>

const int LENGTH = 50;
const int LINE = 4;

int main() {
std::ifstream f("FILE.txt");
std::string s;

for (int i = 1; i <= LINE; i++)
        std::getline(f, s);

std::cout << s;
return 0;
}
查看更多
登录 后发表回答