在这个问题被标记为重复之前。 我已经看过了C++的大部分问题和它们的相对答案。 这些都是我尝试过的链接,没有一个为我工作。 这可能是因为他们使用的是旧版本的C++,而我使用的是最新版本的C++。 以下是我尝试的链接:
现在,复制品都放好了。 我在做一个表达式计算器。 因此,例如,如果用户输入为: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键,那就太好了!
我避免使用字符串以避免解析文本
那个论点没有实际意义。 您可以从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)