在我用ifstream
打开的文件中,获取当前行的行号的最佳方法是什么?因此,我正在读取数据,并且我需要存储它所在的行号,以便稍后在数据与规范不匹配时显示它。
发布于 2011-01-28 04:30:13
如果您不想将自己限制为std::getline
,那么可以使用从std::streambuf
派生的类,它可以跟踪当前的行号:
class CountingStreamBuffer : public std::streambuf { /* see below */ };
// open file
std::ifstream file("somefile.txt");
// "pipe" through counting stream buffer
CountingStreamBuffer cntstreambuf(file.rdbuf());
std::istream is(&cntstreambuf);
// sample usage
is >> x >> y >> z;
cout << "At line " << cntstreambuf.lineNumber();
std::getline(is, str);
cout << "At line " << cntstreambuf.lineNumber();
下面是CountingStreamBuffer
的一个示例实现
#include <streambuf>
class CountingStreamBuffer : public std::streambuf
{
public:
// constructor
CountingStreamBuffer(std::streambuf* sbuf) :
streamBuf_(sbuf),
lineNumber_(1),
lastLineNumber_(1),
column_(0),
prevColumn_(static_cast<unsigned int>(-1)),
filePos_(0)
{
}
// Get current line number
unsigned int lineNumber() const { return lineNumber_; }
// Get line number of previously read character
unsigned int prevLineNumber() const { return lastLineNumber_; }
// Get current column
unsigned int column() const { return column_; }
// Get file position
std::streamsize filepos() const { return filePos_; }
protected:
CountingStreamBuffer(const CountingStreamBuffer&);
CountingStreamBuffer& operator=(const CountingStreamBuffer&);
// extract next character from stream w/o advancing read pos
std::streambuf::int_type underflow()
{
return streamBuf_->sgetc();
}
// extract next character from stream
std::streambuf::int_type uflow()
{
int_type rc = streamBuf_->sbumpc();
lastLineNumber_ = lineNumber_;
if (traits_type::eq_int_type(rc, traits_type::to_int_type('\n')))
{
++lineNumber_;
prevColumn_ = column_ + 1;
column_ = static_cast<unsigned int>(-1);
}
++column_;
++filePos_;
return rc;
}
// put back last character
std::streambuf::int_type pbackfail(std::streambuf::int_type c)
{
if (traits_type::eq_int_type(c, traits_type::to_int_type('\n')))
{
--lineNumber_;
lastLineNumber_ = lineNumber_;
column_ = prevColumn_;
prevColumn_ = 0;
}
--column_;
--filePos_;
if (c != traits_type::eof())
return streamBuf_->sputbackc(traits_type::to_char_type(c));
else
return streamBuf_->sungetc();
}
// change position by offset, according to way and mode
virtual std::ios::pos_type seekoff(std::ios::off_type pos,
std::ios_base::seekdir dir,
std::ios_base::openmode mode)
{
if (dir == std::ios_base::beg
&& pos == static_cast<std::ios::off_type>(0))
{
lastLineNumber_ = 1;
lineNumber_ = 1;
column_ = 0;
prevColumn_ = static_cast<unsigned int>(-1);
filePos_ = 0;
return streamBuf_->pubseekoff(pos, dir, mode);
}
else
return std::streambuf::seekoff(pos, dir, mode);
}
// change to specified position, according to mode
virtual std::ios::pos_type seekpos(std::ios::pos_type pos,
std::ios_base::openmode mode)
{
if (pos == static_cast<std::ios::pos_type>(0))
{
lastLineNumber_ = 1;
lineNumber_ = 1;
column_ = 0;
prevColumn_ = static_cast<unsigned int>(-1);
filePos_ = 0;
return streamBuf_->pubseekpos(pos, mode);
}
else
return std::streambuf::seekpos(pos, mode);
}
private:
std::streambuf* streamBuf_; // hosted streambuffer
unsigned int lineNumber_; // current line number
unsigned int lastLineNumber_;// line number of last read character
unsigned int column_; // current column
unsigned int prevColumn_; // previous column
std::streamsize filePos_; // file position
};
发布于 2011-01-27 13:45:13
从ifstream的角度来看,没有行号。如果您逐行阅读文件,那么您只需自己跟踪它。
发布于 2011-01-27 13:45:51
使用std::getline
逐行读取每一行。保持一个整数来指示您已经读取的行数:将其初始化为0,每次调用std::getline
并成功时,递增它。
https://stackoverflow.com/questions/4813129
复制相似问题