提问者:小点点

在C++中无法检测enter键


在这个问题被标记为重复之前。 我已经看过了C++的大部分问题和它们的相对答案。 这些都是我尝试过的链接,没有一个为我工作。 这可能是因为他们使用的是旧版本的C++,而我使用的是最新版本的C++。 以下是我尝试的链接:

  • 在C++中检测ENTER键
  • https://www.sololearn.com/discuss/1863352/how-can-i-check-that-user-press-enter-key-in-c
  • http://www.cplusplus.com/forum/beginner/2624/
  • https://www.dreamincode.net/forums/topic/398680-detect-enter-key/

现在,复制品都放好了。 我在做一个表达式计算器。 因此,例如,如果用户输入为:2+2*6*9/9,则输出应为14。
我怀疑问题所在的代码位于:

#include <iostream>
#include <vector>

using std::cout;
using std::cin;
using std::string;
using std::vector;

void clear();
void error(string message);

int main() {
    cout << "Enter an expression: ";
    double l_Value = 0, r_Value = 0, result = 0, count = 0, previous_number;
    char op;
        while (cin >> l_Value) { // 1+2*3+6-4/2+3
            if (!cin) {
                error("Invalid operand entered!");
            }
            else {
                bool is_Error = 0; // false
                vector<double> numbers;
                numbers.push_back(l_Value);
                previous_number = l_Value;
                while (cin >> op) {
                    if (op == '\0') {
                        break;
                    }
                    cin >> r_Value;
                    switch (op)
                    {
                    case '+':
                        numbers.push_back(r_Value);
                        previous_number = r_Value;
                        break;
                    case '-':
                        numbers.push_back((-1 * r_Value));
                        previous_number = (-1 * r_Value);
                        break;
                    case '*':
                        numbers.pop_back(); // take out the number
                        r_Value *= previous_number;
                        numbers.push_back(r_Value);
                        previous_number = r_Value;
                        break;
                    case '/':
                        if (r_Value == 0) {
                            error("Sorry, division by zero has occured. Please re-evaluate your expression!\n");
                            is_Error = 1; // true
                            break;
                        }
                        else {
                            numbers.pop_back(); // take out the number
                            previous_number /= r_Value;
                            numbers.push_back(previous_number);
                            break;
                        }
                    }
                }
                if (!is_Error) {
                    for (int i = 0; i < numbers.size(); i++) {
                        result += numbers[i];
                    }
                    cout << result << '\n';
                }
                numbers.clear();
                result = 0;
                l_Value = 0;
                r_Value = 0;
                
            }
        cout << "Enter an expression: ";
    }

    clear();
    return 0;
}

上面的链接似乎没有一个对我有效。
当我按Enter键时,它会要求我提供另一个输入,但这是不应该发生的。 因此,当我使用
cin.get()=='n'或cin.get()==(int)'\n'时,它需要另一个输入。 但是,当我在表达式的末尾加上一个“x”时,它就可以很好地工作了。 所以,我需要“CIN”运算符来帮助我检测表达式末尾的一个Enter字符,然后终止程序。
此处是带“x”的程序的示例运行:

[![作为x-terminator运行][1]][1]
[1]:https://i.stack.imgur.com/orpqa.png

对于enter键和空字符,我不得不按Ctrl+Z来终止程序。 请救命!

正如用户@idclev所提到的,我已经有了一个能工作的字符串程序,但是我正在努力避免使用字符串来计算任何表达式! 所以,如果我能检测到使用字符数据类型按下的enter键,那就太好了!


共2个答案

匿名用户

我避免使用字符串以避免解析文本

那个论点没有实际意义。 您可以从cin读取的内容也可以从std::string读取,没有任何区别。 您只需添加一个步骤:

#include <iostream>
#include <string>
#include <sstream>

int main( ){
    std::string x;
    std::cin >> x;
    if (x == "") {
            std::cout << "user pressed enter (and nothing else)";
    } else {
        double y;
        std::stringstream ss{x};
        ss >> y;
        std::cout << y;
    }
}

这将读取一个std::string。 如果用户只按enter,则字符串将为空。 如果用户输入了一些内容,则将使用else分支,您可以从字符串中提取数字,方法与从cin中提取数字相同(通过使用std::stringstream)。

如果输入中有多个数字,则需要使用getline读取字符串,因为cin(默认情况下)只读取下一个空格。

再一次。。。

如果我使用字符串,在提取字符串中的个位数,两位数或n位数时会很困难。 double数据类型为我提供了这一功能

您可以从stringstream读取一位数或任意位数,读取方式与从cin读取方式完全相同。

我已经用字符串做了一个程序。 我试着避开字符串,看看没有字符串会快多少。

不会再快了。 构造字符串和字符串流可能是微秒级的。 一个用户输入的输入是以秒为单位的,当他们打字速度非常快时,可能是毫秒。

您的方法无法工作,因为按回车键不被视为字符。 当流中没有字符时,尝试读取字符将失败。 它不会将字符设置为\n\r

匿名用户

在外部循环中,您试图读取一个double,但您一直按Enter。 没有要计算的输入,所以它一直尝试读取一个double。 您可以通过以^Z结束输入流来摆脱它,或者您可以给它任何实际的内容来读取,它会尝试将它变成double(这是您的代码明确告诉它要等待的)。

基本上,当您按enter时,它会忽略它,因为
http://www.cplusplus.com/reference/istream/istream/operator%3e%3e/

从流中提取尽可能多的字符,并将它们插入到由sb所指向的流缓冲区对象控制的输出序列中(如果有的话),直到要么输入序列耗尽,要么函数未能插入到sb所指向的对象中。

试着用这个来做实验,看看到底发生了什么。

#include <iostream>
#include <vector>
#include <string>

int main() {
    double x;
    std::cin >> x;
    std::cout << "read this value: " << x << std::endl;

    // this is what while or if will look at
    bool success = !std::cin.fail();
    if (success)
        std::cout << "success" << std::endl;
    else
        std::cout << "failure, loop will exit" << std::endl;
    return 0;
}

在我看来,您应该想要的是一个函数,它将表达式作为字符串,并返回结果,这样您就可以编写单元测试,并确保该函数工作。 您可以将此函数与任何可以放在字符串中的表达式一起使用。 它不必由用户输入。

如果希望用户键入experession,那么只需使用getline(),然后将字符串传递给函数就会容易得多。 在每个变量和字符上使用cin的一个大问题是,用户不知道需要哪种数据类型。 当然,用表达式来猜测并不难,但是您编写了它并调试了它,仍然不知道您未能将正确的数据类型获取到哪个cin。 (这是正常的,顺便说一句--一直在那里,这就是为什么我要分开getline和parse)

相关问题


MySQL Query : SELECT * FROM v9_ask_question WHERE 1=1 AND question regexp '(c++|中|检测|enter|键)' ORDER BY qid DESC LIMIT 20
MySQL Error : Got error 'repetition-operator operand invalid' from regexp
MySQL Errno : 1139
Message : Got error 'repetition-operator operand invalid' from regexp
Need Help?