为什么 "keep_window_open()" 不等待输入字符?

Why "keep_window_open()" doesn't wait for a character to be entered?

我是编程新手,正在尝试自学C++,正在关注"Programming principles and practice using C++"。

我正在尝试做一个练习,在完成其他各种步骤后,要求我

" ...change the body of the loop so that it reads just one double each time around. Define two variables to keep track of which is the smallest and which is the largest value you have seen so far. Each time through the loop write out the value entered. If it’s the smallest so far, write the smallest so far after the number. If it is the largest so far, write the largest so far after the number".

到目前为止我写了以下代码:

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<cmath>
using namespace std;
inline void keep_window_open() { cout<<"\nType a character to exit: "; char ch; cin>>ch; }

int main()
{
double val1 = 0, smallest = 0, largest = 0;
int flag = 0;
while (cin >>val1) {
    if (val1=='|')
        break;
    else
        cout <<val1 <<'\n';
    if (flag==0) {
        smallest = val1;
        cout <<smallest <<" it's the smallest value so far.\n";
    }
    if (val1<smallest) {
        smallest = val1;
        cout <<smallest <<" it's the smallest value so far.\n"; }
    else if (val1>largest) {
             largest = val1;
             cout <<largest <<" it's the largest value so far.\n"; }
    ++flag;
}

keep_window_open();

return 0;
}

我的问题是当我输入一个字符时,例如'c',程序结束,虽然程序应该结束,假设,只有当我输入'|',我得到:

c

Type a character to exit:
Process returned 0 (0x0)     execution time : ...
Press any key to continue.

"keep_window_open()" 不等待输入字符。我只是不明白发生了什么,为什么。有人有线索吗?

问题

while (cin >>val1) 将输入读入双精度值。如果你输入的东西不能像“|”一样读作双精度数那么这将失败并导致你的循环退出。

然后您尝试在 cin 处于错误状态时读取更多输入。

解决方案

调用 cin.clear() 以首先清除所有错误标志,然后 cin.ignore(1000, '\n') 丢弃输入流中留下的所有内容。

inline void keep_window_open() 
{ 
    cout << "\nType a character to exit: "; 
    char ch; 

    cin.clear();
    cin.ignore(1000, '\n');
    cin >> ch; 
}

备注

if (val1=='|')
    break;

此代码永远不会正确,因为如果您尝试输入管道字符,您的 while 循环将在到达它之前失败。

嗯,我认为问题在于您定义循环表达式的方式。 cin 及其运算符“>>”return 都不是您可以使用的真/假值。他们 return 一个 iStream 对象,它可能通过幕后发生的自动转换来可疑地转换为 true 或 false。然而,当无法在您的变量中设置输入时,它们将 return 为 null,就像在尝试将 'c' 放入 double 的情况下,null 转换为 false。

我建议你创建一个简单的 while(true) 循环,当你得到“|”来自用户的字符(作为字符串)你打破了循环。直到那时循环继续。然后在循环内解析您的值并根据您的逻辑(最小值/最大值)对其进行处理