2017-04-17 30 views
0

我有我不能改变的输入文件,具有略微不同线从输入文件C++读取与istream的操作符重载

Supercar HTT Technologies 10 2 
Motorcycle Honda 40 1 
... 

我为了中的值读入我的数据重载>>操作符结构,主要内容如下:

class Vehicles{ 
private: 
string type; //type of vehicle, i.e. car/motorcycle 
string manufacturer; 
string manufacturer2ndPart //not a good idea, but this is what I'm using 
          //to get the second part of the manufacturer ("Technologies") 
int milesPerGallon; 
int numPrevOwn //number of previous owners 
public: 
... 

friend istream &operator >> (istream &is, Vehicles &Vec){ 
is >> Vec.type >> Vec.manufacturer >> Vec.milesPerGallon >> Vec.numPrevOwn; 
return is; 
    } 
}; 

这对第一线工作正常,但打破了输入文件的第二行,因为它试图“40”读成manufacturer2,而不是milesPerGallon。解决这个问题最好的办法是什么?我想避免手动读取所有内容,因为这会破坏操作员重载的目的。

+0

刚刚编辑了一下这篇文章。第一行读入并输出完全正常。第二行读入字符串“manufacturer2ndPart”中的“40”,而不是读入int milesPerGallon,从而使numPrevOwn成为内存中的任何值。 –

+1

这些值是如何分开的? – Jonas

+2

您必须知道输入文件的格式。例如,你怎么知道它没有与制造商“技术”一起输入“Supercar HTT”?应该有一条规则,例如“列至少分隔2个空格”或“列总是14个字符宽” – nwp

回答

1

你的基本问题是流的>>所有的停止当他们遇到空白,并且你的输入文件包含空格作为数据,而不是作为忽略的东西。因此,您需要根据线路需要不同数量的字符串的问题。

一般来说,你最好一次读一整行到一个字符串(例如使用std::getline())。然后在试图实际提取它们之前,检查字符串以计算它实际包含的字段数。换句话说,不要使用流操作符来读取文件(或写入文件)。

它可能还会稍微改变文件格式,所以当字符串字段的开始时它变得很明显。例如,像

"Supercar" "HTT Technologies" 10  2 
"Motorcycle" "Honda" 40  1 

你仍然需要一次读取一条线,但使用"分隔字符串可以更容易地识别开始和每个每个字符串,并处理含有它们的格式空格(除了换行符)。如果您需要在字符串中包含"字符,请指定它将在前面加上\,并相应地解析输入。

显然,任何读取或写入此类文件的代码都需要遵守相同的协议。阅读代码需要处理错误(例如,不符合协议的文件)。

+0

似乎是一个好主意,使用getline,我会结合这与stringstream,是吗?我只是有点困惑,我怎么会真正确定有多少“字段“中存在字符串,因为它看起来像以前一样的读取过程。 不幸的是,我不能改变文件格式,但我希望我能:P –

+2

你可以使用'stringstream'。如果您无法更改文件格式,则需要直接检查每一行(例如,循环中的每个字符),并计算出在整数值之前可能有多少个字符串数据 - 大概在最后。你需要处理像“SuperCar6 Company Fumbler#2 10 20”这样的输入 - 这可以通过向后反向处理字符串,计数数字和空格来处理,直到达到最后一个字符串数据的末尾。 – Peter