あなたの主な問題は、ストリームから直接 >> で整数を読み取っていることです。これをストリームからの文字列の読み取りと組み合わせることは、悪い考えです。文字列を読み取ると改行が削除されますが、>> で読み取っても改行は削除されません。
2 つの形式を混在させないことをお勧めします。常に >> を使用するか、常に getline() を使用してください。注: 私は最高と言っているのではなく、最も簡単だと言っています。トレードオフと、使用方法の違いを補う方法を理解すれば、それらを一緒に使用できます。
したがって、数値の行を文字列に読み取ってから、文字列を解析する方が簡単です。
std::string lineOfNumbers;
std::getline(file, lineOfNumbers);
// Now you have read all the numbers and the new line.
std::stringstream streamOfNumbers(lineOfNumbers);
while(streamOfNumbers >> value)
{
// Do something with number.
}
ほとんどの場合、次の使用は間違っています。
while(!file.eof())
これは、eof を過ぎて読み取るまで EOF フラグが設定されないためです。最後の読み取りは、eof までではなく、eof まで読み取ることに注意してください。したがって、利用可能なデータがなくてもループに入ります。
標準的なパターンは次のとおりです。
while(file >> object)
{
// Action
}
これを念頭に置いて、必要なすべての情報 (つまり 2 行) を表すクラスを定義します。シンプルなバージョンは
class TwoLineReader
{
public:
std::string line1;
std::string line2;
};
std::istream& operator>>(std::istream& stream, TowLineReader& record)
{
std::getline(stream, record.line1);
std::getline(stream, record.line2);
return stream;
}
TowLineReader obj;
while(file >> obj)
{
// Do stuff
}
行を読むだけなら、これで問題ありません。
しかし、データには構造があるように見えます。したがって、データを表すクラスを作成し、データをその構造に直接読み込みます。だから、これは私がすることです。また、while() ループをアルゴリズムに置き換えます。
ヘッダー
#include <algorithm>
#include <iterator>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
/*
* Example Data
David Beckham
80 90 100 20 50
Ronaldinho Gaucho
99 80 100 20 60
*/
クラス:
class Player
{
std::string name;
std::vector<int> goals;
// Stream operator that reads a platers name and his goals.
friend std::istream& operator>>(std::istream& stream, Player& record)
{
// Read the name
std::getline(stream, record.name);
// Read the line of goals.
// Copies the data into goals.
std::string scores;
std::getline(stream, scores);
// std::copy replaces a while loop that pushes each number into the vector.
std::stringstream scorestream(scores);
std::copy( std::istream_iterator<int>(scorestream),
std::istream_iterator<int>(),
std::back_inserter(record.goals));
return stream;
}
};
使用法:
int main()
{
std::ifstream dataFile("data");
std::vector<Player> players;
// Copy all players into a vetor
std::copy( std::istream_iterator<Player>(dataFile),
std::istream_iterator<Player>(),
std::back_inserter(players));
}