std::fstream
オブジェクトに 2 行目からテキスト ファイルの読み取りを開始させるにはどうすればよいですか?
8 に答える
getline() を使用して最初の行を読み取り、次にストリームの残りの読み取りを開始します。
ifstream stream("filename.txt");
string dummyLine;
getline(stream, dummyLine);
// Begin reading your stream here
while (stream)
...
(std::getline に変更 (thanks dalle.myopenid.com))
ストリームの無視機能を使用できます。
ifstream stream("filename.txt");
// Get and drop a line
stream.ignore ( std::numeric_limits<std::streamsize>::max(), '\n' );
// Get and store a line for processing.
// std::getline() has a third parameter the defaults to '\n' as the line
// delimiter.
std::string line;
std::getline(stream,line);
std::string word;
stream >> word; // Reads one space separated word from the stream.
ファイルを読み取る際のよくある間違い:
while( someStream.good() ) // !someStream.eof()
{
getline( someStream, line );
cout << line << endl;
}
これは次の理由で失敗します: 最後の行を読み取るときに、EOF マーカーを読み取っていません。したがって、ストリームはまだ正常ですが、ストリームに読み取るデータが残っていません。したがって、ループに再び入ります。その後、std::getline() は someStream から別の行を読み取ろうとして失敗しますが、それでも std::cout に行を書き込みます。
簡単な解決策:while( someStream ) // Same as someStream.good()
{
getline( someStream, line );
if (someStream) // streams when used in a boolean context are converted to a type that is usable in that context. If the stream is in a good state the object returned can be used as true
{
// Only write to cout if the getline did not fail.
cout << line << endl;
}
}
正しい解決策:
while(getline( someStream, line ))
{
// Loop only entered if reading a line from somestream is OK.
// Note: getline() returns a stream reference. This is automatically cast
// to boolean for the test. streams have a cast to bool operator that checks
// good()
cout << line << endl;
}
より効率的な方法は、std::istream::ignoreで文字列を無視することです
for (int currLineNumber = 0; currLineNumber < startLineNumber; ++currLineNumber){
if (addressesFile.ignore(numeric_limits<streamsize>::max(), addressesFile.widen('\n'))){
//just skipping the line
} else
return HandleReadingLineError(addressesFile, currLineNumber);
}
もちろん、HandleReadingLineError は標準ではなく手作りです。最初のパラメーターは、抽出する最大文字数です。これが正確に numeric_limits::max() である場合、制限はありません: cplusplus.com のリンク: std::istream::ignore
多くの行をスキップする場合は、getline の代わりにそれを使用する必要があります。ファイルで 100000 行をスキップする必要がある場合、getline では 22 秒でしたが、約 1 秒かかりました。
getline() を 1 回呼び出して、最初の行を破棄します
他にも方法はありますが、問題はこれです、最初の行がどれくらいの長さになるかわかりませんよね?そのため、最初の '\n' がどこにあるかがわかるまで、スキップすることはできません。ただし、最初の行の長さがわかっている場合は、単にそれを通り過ぎてから読み始めることができます。これはより高速です。
したがって、最初の方法は次のようになります。
#include <fstream>
#include <iostream>
using namespace std;
int main ()
{
// Open your file
ifstream someStream( "textFile.txt" );
// Set up a place to store our data read from the file
string line;
// Read and throw away the first line simply by doing
// nothing with it and reading again
getline( someStream, line );
// Now begin your useful code
while( !someStream.eof() ) {
// This will just over write the first line read
getline( someStream, line );
cout << line << endl;
}
return 0;
}
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
string textString;
string anotherString;
ifstream textFile;
textFile.open("TextFile.txt");
if (textFile.is_open()) {
while (getline(textFile, textString)){
anotherString = anotherString + textString;
}
}
std::cout << anotherString;
textFile.close();
return 0;
}
#include <fstream>
#include <iostream>
using namespace std;
int main ()
{
char buffer[256];
ifstream myfile ("test.txt");
// first line
myfile.getline (buffer,100);
// the rest
while (! myfile.eof() )
{
myfile.getline (buffer,100);
cout << buffer << endl;
}
return 0;
}