在我用ifstream
打开的文件中获取当前行的行号的最佳方法是什么?因此,我正在读取数据,我需要存储它所在的行号,以便以后可以在数据与规格不匹配时显示。如何从C++文件中获取行号?
10
A
回答
9
从ifstream的观点来看,没有行号。如果你逐行读入文件,那么你只需要自己跟踪它。
4
使用std::getline
逐一读取每一行。保留一个整数,指出已阅读的行数:将其初始化为零,并且每次调用std::getline
并成功时,将其递增。
8
如果不想限制自己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
};
0
一种效率低下但死亡的简单方法是有一个给定流的函数,它计算从流开头到当前位置的新行字符。效率低下,因为如果您想知道多个流位置的线路,则必须多次调用它,从每次流的开始处开始计算。在我正在处理的一些代码中,如果遇到无效输入,我只想知道行号,在这种情况下立即中止导入。由于该函数只被调用一次,所以低效率并不是真正的问题。
这是我做这个代码:
方法int getCurrentLine(std::istream& is)
{
int lineCount = 1;
is.clear(); // need to clear error bits otherwise tellg returns -1.
auto originalPos = is.tellg();
if (originalPos < 0)
return -1;
is.seekg(0);
char c;
while ((is.tellg() < originalPos) && is.get(c))
{
if (c == '\n') ++lineCount;
}
return lineCount;
}
一个优点是,在其中构造流的地方不需要任何改变,你只需要调用在你需要它的功能。以下是一个完整的示例:
#include <iostream>
#include <sstream>
int getCurrentLine(std::istream& is)
{
int lineCount = 1;
is.clear(); // need to clear error bits otherwise tellg returns -1.
auto originalPos = is.tellg();
if (originalPos < 0)
return -1;
is.seekg(0);
char c;
while ((is.tellg() < originalPos) && is.get(c))
{
if (c == '\n') ++lineCount;
}
return lineCount;
}
void ReadDataFromStream(std::istream& s)
{
double x, y, z;
while (!s.fail() && !s.eof())
{
s >> x >> y >> z;
if (!s.fail())
std::cout << x << "," << y << "," << z << "\n";
}
if (s.fail())
std::cout << "Error at line: " << getCurrentLine(s) << "\n";
else
std::cout << "Read until line: " << getCurrentLine(s) << "\n";
}
int main(int argc, char* argv[])
{
std::stringstream s;
s << "0.0 0.0 0.0\n";
s << "1.0 ??? 0.0\n";
s << "0.0 1.0 0.0\n";
ReadDataFromStream(s);
std::stringstream s2;
s2 << "0.0 0.0 0.0\n";
s2 << "1.0 0.0 0.0\n";
s2 << "0.0 1.0 0.0";
ReadDataFromStream(s2);
return 0;
}
相关问题
- 1. 如何从c#中的文本文件中获取某些行?
- 2. 从文件片段获取行号
- 3. 获取文件的行号
- 4. C#获取行号
- 5. 如何从Response.Header获取文件名? C#
- 6. 从文件中获取行
- 7. 如何从C#中获取/获取CAB FileUnique版本号?
- 8. 如何从冒号(:)读取C#中的分隔文本文件
- 9. 如何从c中的文本文件读取多行文件#
- 10. 如何从C++文件夹中获取文件名
- 11. 如何从c#中的文件“template.docx.amp”获取文件名?
- 12. ASP.Net获取源文件中的行号
- 13. 如何从c/C++中的文本文件读取一行?
- 14. 如何从符号(.pdb)文件中确定C#方法的文件和行号?
- 15. 获取行号从列表视图C#
- 16. 我们如何从pdb文件获取源文件修订号?
- 17. 如何从C#中MS Project的XML文件中获取文本?
- 18. 如何从网络核心中的异常中获取行号和文件名?
- 19. 如何在java中使用读取文件时获得行号
- 20. 如何在Perl中获取文件名和行号?
- 21. 如何从给定的XSLT文件中获取版本号。
- 22. 如何从设备文件中获取主号码
- 23. 如何从statsmodels.api.OLS获取条件编号?
- 24. 如何从C#中获取Word文档的文件名?
- 25. 如何从c#中的文本文件获取数据
- 26. 如何从文本文件中获取代理c#/ .net?
- 27. 您可以从C++ Lib文件中获取信息,例如如何从Jar文件中获取信息?
- 28. C#从文本文件获取数据用分号
- 29. 如何获取行号?
- 30. 从缩小的JavaScript文件中获取错误的行号
注意:您可以逐行阅读(`std :: getline`),或者只是计算经过的\ n字符的数量。 – 2011-01-27 09:07:44