ifstream
で開いたファイルの現在の行の行番号を取得する最も良い方法は何ですか?だから私はデータを読み込んでいるので、データが仕様と一致しないと後で表示できるように、行番号を格納する必要があります。C++のファイルから行番号を取得する方法は?
10
A
答えて
9
ifstreamの観点からは、行番号はありません。ファイルを1行ずつ読み込むと、それを自分で追跡するだけです。
4
std::getline
を使用して、各行を1つずつ読み込みます。読み込んだ行数を示す整数を0に初期化し、std::getline
を呼び出して成功するたびにインクリメントします。
8
あなたはは、あなたがstd::streambuf
から派生したクラスを使用することができ、かつこれは、現在の行番号を追跡し、std::getline
に自分自身を制限しない場合:ここで
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. .llファイルからソース行番号を取得する方法LLVM
- 2. pythonで.mobiファイルからISBN番号を取得する方法
- 3. 行番号でXDocumentからXElementを取得する方法
- 4. 行番号からカーソルを取得する方法
- 5. テーブルからperticular行番号を取得する方法
- 6. asyncで行番号を取得する方法C#
- 7. javascriptエラー行番号から実際の行を取得する方法
- 8. スタイルDOMオブジェクトからソースファイルの行番号を取得する方法は?
- 9. QTableViewのrigth-clickから行番号を取得する方法は?
- 10. C/C++ Linuxでプロセッサシリアル番号を取得する方法
- 11. cheerio.jsのノード行番号を取得する方法は?
- 12. 現在の行番号を取得する方法は?
- 13. C++で列番号を取得する方法は?
- 14. 特定のJetBrains.ReSharper.Psi.IDeclaredElementのファイル名と行番号を取得する方法は?
- 15. Hikvisionカメラから歩行者番号を取得する方法は?
- 16. PCAPファイルでプロトコル番号を取得する方法は?
- 17. ID番号からオブジェクトインスタンスの情報を取得する方法
- 18. ユーザから1つの番号を取得する方法
- 19. ユーザーからアプリケーションのバージョン番号を取得する方法
- 20. 特定のXSLTファイルからバージョン番号を取得する方法。
- 21. OnDrawColumnCellイベントで行番号を取得する方法は?
- 22. SolarisでBACKTRACE(関数+行番号)を取得する方法は?
- 23. if文の後にテキストファイルから行番号を取得する方法
- 24. XMLBeansのXMLErrorから行番号情報を取得する方法
- 25. jqGridで行番号ごとにページ番号を取得する方法
- 26. タイル通知から番号を取得する方法
- 27. pexpectから番号出力を取得する方法
- 28. SMSから電話番号を取得する方法android
- 29. アンドロイド携帯から電話番号を取得する方法
- 30. ランダムオブジェクトからよりユニークな番号を取得する方法
注:1行ずつ( 'std :: getline')読み込むか、単に渡す' \ n'文字の数を数えることができます。 –
@Matthieu:これは、それぞれの '\ n'があなたのプラットフォーム上の改行を意味すると仮定しています。 – rubenvb
@rubenvb:テキストモードでは '\ n'は改行を表し、' iostream'はロケールを使ってそれを作る(両方の読み込み書き込み)。バイナリモードで読み込んだ場合、変換は行われません。 –