std::cin 替换为更复杂的对象

std::cin with more complex objects

提问人:Al.G. 提问时间:8/29/2016 最后编辑:Al.G. 更新时间:8/30/2016 访问量:77

问:

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

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

这就是问题所在 - 永远不会获取彩色线条,即不执行第二个循环。

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

我试图在 ColorfulLines 部分之前放置一些随机单词,希望当第一个循环失败时,第二个循环将开始从“红色”字符串读取,但事实并非如此。

如何解决这个问题?

C++ 文件-IO C++14 IOstream

评论

0赞 Al.G. 8/30/2016
对投反对票的原因的解释将不胜感激。
0赞 ildjarn 8/30/2016
我没有投反对票,但我敢打赌,这是因为您在异地发布了相关代码,而不是直接在您的问题中。(请不要在以后这样做。
0赞 Al.G. 8/30/2016
@ildjarn相关代码都在问题中,我只跳过了运算符重载,我认为这里没有必要。(当然还有 int main 和 co.)。我错了吗?我想如果我只把最重要的部分留在这里,而不是把整个垃圾留在那里会更好。>>

答:

5赞 Baum mit Augen 8/29/2016 #1

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

要解决此问题,请在第一个循环中断后重置错误状态

std::cin.clear();