在我用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. 從文件中獲取行號
- 2. 如何從c#中的文本文件中獲取某些行?
- 3. 如何從C++文本文件中獲取特定行?
- 4. 從文件片段獲取行號
- 5. 如何從MySQL表中獲取行號?
- 6. 如何從C++中的文本文件中讀取Unicode符號
- 7. 如何從C++中的括號中獲取文本?
- 8. 獲取文件的行號
- 9. 如何從Response.Header獲取文件名? C#
- 10. 如何從C#目錄獲取文件
- 11. C#獲取行號
- 12. 如何從Style DOM對象獲取源文件行號?
- 13. 關於如何從python文本文件中獲取行號的任何提示?
- 14. 從文件中獲取行
- 15. 如何從C#中獲取/獲取CAB FileUnique版本號?
- 16. 如何從冒號(:)讀取C#中的分隔文本文件
- 17. 如何從c中的文本文件讀取多行文件#
- 18. 如何從C++文件夾中獲取文件名
- 19. 如何從c#中的文件「template.docx.amp」獲取文件名?
- 20. 如何從c/C++中的文本文件讀取一行?
- 21. 如何從符號(.pdb)文件中確定C#方法的文件和行號?
- 22. ASP.Net獲取源文件中的行號
- 23. 獲取行號從列表視圖C#
- 24. 我們如何從pdb文件獲取源文件修訂號?
- 25. 如何從C#中MS Project的XML文件中獲取文本?
- 26. 如何從XmlElement或XPathNavigator獲取行號
- 27. 如何從行號獲取光標
- 28. 從文件中獲取文本C#
- 29. 如何從網絡核心中的異常中獲取行號和文件名?
- 30. 如何讀取objective-c文件中的特定行號?
注意:您可以逐行閱讀(`std :: getline`),或者只是計算經過的\ n字符的數量。 – 2011-01-27 09:07:44