使用 istream 运算符重载从输入文件 C++ 读取

Reading from input file C++ with istream operator overloading

我有一个无法更改的输入文件,其中的行略有不同

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。解决这个问题的最佳方法是什么?我想避免手动读取所有内容,因为这违背了我的运算符超载的目的。

您的基本问题是流的 >> 重载在遇到空格时全部停止,并且您的输入文件包含空格作为数据而不是作为要忽略的内容。因此,您的问题是根据行需要不同数量的字符串。

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

稍微更改文件格式可能也有好处,这样可以使字符串字段的开头很明显。例如,像

这样的格式
"Supercar"  "HTT Technologies"   10     2
"Motorcycle" "Honda"    40     1

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

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