您的主要问题是您正在使用 >> 直接从流中读取整数。这与从流中读取字符串相结合是一个坏主意。读取字符串会删除新行,使用 >> 读取不会删除新行。
最好不要混合这两种形式。要么总是使用>>,要么总是使用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。因此,即使没有可用数据,您也将进入循环。
标准模式是:
while(file >> object)
{
// Action
}
考虑到这一点,我将定义一个代表您想要的所有信息的类(即两行)。一个简单的版本是
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));
}