出于不同目的重复读取由空格(或其他分隔符)分隔的双精度列表
我对 C++ 非常陌生,遇到了以下问题。
我的目标: 我想要一个执行以下操作的代码:
- 用户输入包含以某种方式分隔的双精度数的行
- 双精度数被解析为双精度数数组
- 对数组进行计算(*)。例如,它的总和
- 如果用户不停止循环,它会读取一个新行,然后循环回到 1。
- 一旦用户中断第一个循环(通过输入空行或类似的内容),就会开始一个新循环。
- 用户输入包含以某种方式分隔的双精度数的行
- 双精度数将被解析为双精度数数组
- 对数组进行计算(**)。例如它的平均值。
- 用户制动第二个循环。
- 程序退出。
我的代码:
#include <iostream>
int main()
{
do {
double x1, x2, x3, y1, y2, y3;
std::cin >> x1 >> y1 >> x2 >> y2 >> x3 >> y3;
if (!std::cin){
break;
}
std::cout << "\n The sum is: " << (x1+y1+x2+y2+x3+y3) << "\n";
} while (1);
do {
double x1, x2, x3, y1, y2, y3;
std::cin >> x1 >> y1 >> x2 >> y2 >> x3 >> y3;
if (!std::cin){
break;
}
std::cout << "\n The average is: " << (x1+y1+x2+y2+x3+y3)/6 << "\n";
} while (1);
return 0;
}
问题: 当我尝试停止第一个循环,并通过按 CTRL-D 或给出一个字母作为输入移动到第二个循环时,程序将退出并跳过第二个循环。我意识到这与cin
机制有关,但我未能治愈它。
问题:我应该如何编程?解决这个问题最痛苦的方法是什么?提前致谢!
I am very much new into C++ and I ran into the following problem.
My goal:
I want to have a code which does the following:
- The user enters a line containing doubles separated somehow
- The doubles are being parsed into an array of doubles
- A computation(*) on the array takes place. For example its sum
- If the user doesn't brake the loop, it reads a new line, and loop back to 1.
- Once the user broke the first loop (by entering empty line or something like that), a new one starts.
- The user enters a line containing doubles separated somehow
- The doubles are being parsed into an array of doubles
- A computation(**) on the array takes place. For example its average.
- User brakes the second loop.
- Program quits.
My code:
#include <iostream>
int main()
{
do {
double x1, x2, x3, y1, y2, y3;
std::cin >> x1 >> y1 >> x2 >> y2 >> x3 >> y3;
if (!std::cin){
break;
}
std::cout << "\n The sum is: " << (x1+y1+x2+y2+x3+y3) << "\n";
} while (1);
do {
double x1, x2, x3, y1, y2, y3;
std::cin >> x1 >> y1 >> x2 >> y2 >> x3 >> y3;
if (!std::cin){
break;
}
std::cout << "\n The average is: " << (x1+y1+x2+y2+x3+y3)/6 << "\n";
} while (1);
return 0;
}
The Problem:
When I try to stop the first loop, and move to the second by either hitting CTRL-D
or giving a letter as input, then the program quits and skips the second loop. I realized that it relates to the cin
mechanism, but I failed to cure it.
The question: How should I program this? What is the least painful manner to overcome the problem? Thanks in advance!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这是因为当您尝试读取字母或 EOF (Ctrl-D) 时,这会将流的状态设置为错误状态。一旦发生这种情况,流上的所有操作都会失败(直到您重置它)。这可以通过调用clear()来完成
我不会使用这种技术。
我会使用类似空行的东西作为循环之间的分隔符。因此,代码如下所示:
试试这个:
注意:在 C++ 中,当数字以空格分隔时,流效果最佳。因此,只需使用空格或制表符来分隔数字即可。
// 或者我们可以稍微模板化代码:
This is because when you try and read a letter or EOF (Ctrl-D) this sets the state of the stream into a bad state. Once this happens all operations on the stream fail (until you reset it). This can be done by calling clear()
I would not use this technique.
I would use something like an empty line as a separator between loop. Thus the code looks like this:
Try this:
Note: in C++ streams work best when numbers are space separated. So it is easy just use space or tab to separate the numbers.
// Or we could templatize the code slightly:
使用 std::cin.get()。它将在第一个输入的字符后返回。在这种情况下,您不需要循环,而是需要一些东西。像这样:
Use std::cin.get(). It will return after the first entered character. You won't need loops in this case, but rather get smth. like this:
如果 std::cin 收到错误类型的输入,它将进入失败状态 - 您可以使用
(!std::cin)
进行测试。但输入数据也保留在流中。因此,除了检查失败状态之外,您还必须清除失败状态(std::cin.clear();)并从输入流中删除未读数据(std:: cin.ignore();):
我还添加了一个
cout
,它显示了实际循环的可用性。If std::cin gets input of wrong type it goes into fail-state - which you test with
(!std::cin)
. But also the input-data is left on the stream.So additionally to check the fail-state you have to clear the fail-state (
std::cin.clear();
)and remove the unread data from input-stream (std::cin.ignore();
):I also added an
cout
which shows the actual loop for usability.您确实需要重新考虑您的用户界面。
怎么样
使用cout>> aString 来获取关键字,然后像现在一样获取数字。
You really need to rethink you UI.
How about
Use cout >> aString to get the keyword, then get the numbers the same way you do now.