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

标签 c++ input operator-overloading 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”读入制造商2,而不是milesPerGallon。解决这个问题的最佳方法是什么?我想避免手动读取所有内容,因为这违背了运算符重载的目的。

最佳答案

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

一般来说,您最好一次将整行读取为字符串(例如使用 std::getline())。然后检查该字符串以计算出它实际包含的字段数量,然后再尝试实际提取它们。换句话说,不要使用流运算符从文件中读取(或写入)。

稍微改变一下文件格式也可能是值得的,这样字符串字段的开头就很明显了。例如,类似的格式

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

您仍然需要一次读取一行,但是使用 " 来分隔字符串可以更轻松地识别开头和每个字符串,并处理包含空格(其他而非换行符)。如果您需要在字符串中包含 " 字符,请指定其前面带有 \,并相应地解析输入。

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

关于c++ - 使用 istream 运算符重载从输入文件读取 C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43447384/

相关文章:

c++ - C++中的字符串切片

c# - C++ 到 C#,static_cast 到枚举

python - 如何在套接字中使用 raw_input

javascript - 按下 ENTER 键时更改表单标签内的输入值

c++ - 从 C++ 中的 vector 继承类调用 super 运算符==

c++ - map 键没有可行的重载 '=' 错误

c++ 多项式复制构造函数和 ostream 覆盖导致内存泄漏?!

C++ std::set<string> 字母数字自定义比较器

c++ - 重载左移和右移运算符(cin 和 cout)

html - 如何在不影响提交按钮点击动画的情况下进行转换?