具有更复杂对象的std :: cin

时间:2016-08-29 15:52:20

标签: c++ c++11 file-io c++14 iostream

我有一个文本文件,它首先描述了一些行,然后描述了一些彩色的行:

1 2    3  4
5 6    7  8 
9 10   11 12

red    1 0 0    1 2    3 4
green  0 1 0    5 6    7 8
blue   0 0 1    9 10   11 12

执行时每个部分的行数未知 我为这些结构重载了std::cin >>运算符:

struct Point { int x, y; }
struct Line { Point a, b; }
struct Color { float r, g, b; std::string name; };
struct ColorfulLine { Line line; Color color; };

(此处的完整示例:http://ideone.com/bMOaL1 [已经有效 - 根据接受的答案进行编辑])
现在我需要使用LinesColorfulLines

来迭代文件
Line line;                                                     
while(cin >> line) { cout << "We've got a line!\n"; }              

ColorfulLine color_line;                                         
while(cin >> color_line) { cout << "We've got a colorful line!\n"; } 

// actually I'm putting them into std::lists but I skipped this part for simplicity

这就是问题 - 从不提取彩色线条,即不执行第二个循环。

我有一个假设为什么它发生但却不知道如何解决它:
std::cin尝试获取第4行时,它会失败,因为不是数字而是字符串“red”。
接下来,在第二个while循环中,std :: cin尝试读取一个字符串(Color.name),但它看到一个数字,然后也失败了。

我试图在ColorfulLines部分之前添加一些随机单词,希望当第一个循环失败时,第二个循环将从“红色”字符串开始读取,但它没有。

如何解决此问题?

1 个答案:

答案 0 :(得分:5)

第一次循环中断后,std::cin处于错误状态。这就是为什么循环首先突破的原因。对坏流执行读取会立即失败,因此永远不会输入第二个循环。

要解决此问题,请在第一个循环中断

后重置错误状态
std::cin.clear();