使用 top() 时收到错误 "cannot dereference out of range deque iterator"
Recieving error "cannot dereference out of range deque iterator" when utilizing top()
我正在创建一个简单的程序来评估 post 修复表达式,但由于 "Expression: cannot dereference out of range deque iterator" 每当它到达操作数变量的赋值时,它在成功编译后不会 运行在第 24 和 26 行。当程序仅在用数字值填充堆栈后才到达该点时,为什么它 运行 不正确?
#include <iostream>
#include <stack>
#include <string>
#include <cctype>
using namespace std;
int main()
{
stack<int> mystack;
string answer;
int result;
string done = "Y";
while (done == "Y" || done == "y") {
cout << "Please enter the RPN expression to be evaluated: ";
getline(cin,answer);
for(int i = 0; i < answer.length(); i++) {
if(answer[i] == ' ' || answer[i] == ':') {
continue;
}
if (isdigit(answer[i]) == false) {
cout << "Token = " << answer[i];
int operand2 = mystack.top();
mystack.pop();
int operand1 = mystack.top();
mystack.pop();
cout << " Pop " << operand2 << " Pop " << operand1;
if(answer[i] == '+') { //operation statements
result = operand1 + operand2;
}
else if(answer[i] == '-') {
result = operand1 - operand2;
}
else if(answer[i] == '*') {
result = operand1 * operand2;
}
else if(answer[i] == '/') {
result = operand1 / operand2;
}
mystack.push(result); //result returns to stack
cout << " Push " << result << endl;
}
else if(isdigit(answer[i]) == true){
int operand = 0;
while(i < answer.length() && isdigit(answer[i]) == true) {
operand = (operand*10) + (answer[i] - '0');
i++;
}
i--;
mystack.push(operand);
cout << "Token = " << operand << " Push " << operand << endl;
}
}
cout << "Token = Pop " << mystack.top() << endl << endl;
mystack.pop();
cout << "type 'Y' or 'y' to continue or type any other letter to quit: ";
getline(cin, done);
}
}
这里有一个简单的解决方法。此版本使用 int 并使用字符串堆栈。通过在整个文件中将 int
替换为 double
,这可以很容易地转换为双打,
这使用 getline() 和 istringstream 来解析输入。
它还使用字符串流将数字转换为字符串并返回。
从每一行解析多个单词时必须小心。此代码将输入行重定向到 ss,一个 istringstream 对象,然后从该对象中获取标记。
此外,如果您键入“s”,这将打印堆栈。
最后,您可以用一系列 space 分隔的数字任意加载堆栈,或者您可以一次输入一个数字。输入运算符时使用堆栈。
#include <iostream>
#include <stack>
#include <string>
#include <sstream>
///////////////////////
/// top_and_pop()
/// Save the top value from a stack, and then pop the stack
/// If the stack is empty, return the string "0".
/// If the stack was not empty, return the popped element.
std::string top_and_pop(std::stack<std::string> &stack)
{
std::string return_string;
if (stack.empty()) {
return_string = "0";
std::cout << "Stack Empty, returning 0" << std::endl;
} else {
return_string = stack.top();
std::cout << "Popping " << return_string << std::endl;
stack.pop();
}
return return_string;
}
//////////////////////
/// is_number
/// Parse number into a int using std::stringstream.
/// If successful, then, the stringstream will be empty.
/// Return: true if the str would successfully parse as a int
bool is_number(const std::string &str)
{
std::istringstream ss(str);
int number;
ss >> number;
if (!ss.fail() && ss.eof())
return true;
ss >> std::ws; // not needed in this program, because we already parsed the
// input to a single word without whitespace. Needed for parsing a single line
// that may contain any set of chars.
return !ss.fail() && ss.eof();
}
/////////////////////
/// is_operator
/// return false if str is not a single character or if an operator is not found
/// acceptable operators are anyof "+-*/"
bool is_operator(const std::string &str)
{
return (str.length() == 1 &&
str.find_first_not_of("+-*/") == std::string::npos);
}
/////////////////////
/// string_to_int
/// convert string to int
/// Check to be sure string can convert to a int before calling
/// if conversion fails, return 0;
int string_to_int(const std::string &str)
{
std::stringstream stream;
int number = 0;
stream << str;
stream >> number;
return number;
}
//////////////////////
/// stack_to_string
///
/// print elements of stack
std::string stack_to_string(std::stack<std::string> stack)
{
std::string return_string;
while (!stack.empty()) {
return_string += stack.top() + " ";
stack.pop();
}
return return_string;
}
int main()
{
std::stack<std::string> mystack;
std::string input_line;
bool done = false; /// flag to indicate that calcualtor is closing
std::string token_str;
int operand1, operand2, result;
std::cout
<< "Please enter an RPN expression. Expression may consist of any \n"
"combination of space-separated numbers or operators.\n"
"Operators may include '+', '-', '*', '/'. The stack is initialized\n"
"with an unlimited supply of zeroes.\n\n"
"Type 's' to print the current stack.\n"
"To exit, type a 'y'" << std::endl;
do {
getline(std::cin, input_line);
std::stringstream ss(input_line);
/// loop through all tokens in this input line
while (ss >> token_str) {
// Only numbers are allowed on the stack.
// If the current token is a number, push it on the stack as a string
if (is_number(token_str)) {
mystack.push(token_str);
} else if (is_operator(token_str)) {
operand2 = (int) string_to_int(top_and_pop(mystack));
operand1 = (int) string_to_int(top_and_pop(mystack));
// switch does not accept string as a type, and we checked to ensure
// it is a single character operand that is handled in the switch
switch (token_str[0]) {
case '+':result = operand1 + operand2;
break;
case '-':result = operand1 - operand2;
break;
case '*':result = operand1 * operand2;
break;
case '/':
if (operand2 == 0) {
std::cout << "Error: Cannot divide by zero" << std::endl;
continue; // don't push result, take new input.
} else {
result = operand1 / operand2;
}
break;
// default case not needed as we already checked operator, but
// for error checking, we include it
default:std::cout << "Operator not found" << std::endl;
continue;
}
mystack.push(std::to_string(result));
std::cout << " Push result " << result << " " << std::endl;
} else if ("Y" == token_str || "y" == token_str) {
done = true;
} else if ("stack" == token_str || "s" == token_str) {
std::cout << "stack: ";
std::string stack_dump = stack_to_string(mystack);
std::cout << stack_dump << std::endl;
} else {
std::cout << "Invalid input." << std::endl;
}
}
}
while (!done);
}
我正在创建一个简单的程序来评估 post 修复表达式,但由于 "Expression: cannot dereference out of range deque iterator" 每当它到达操作数变量的赋值时,它在成功编译后不会 运行在第 24 和 26 行。当程序仅在用数字值填充堆栈后才到达该点时,为什么它 运行 不正确?
#include <iostream>
#include <stack>
#include <string>
#include <cctype>
using namespace std;
int main()
{
stack<int> mystack;
string answer;
int result;
string done = "Y";
while (done == "Y" || done == "y") {
cout << "Please enter the RPN expression to be evaluated: ";
getline(cin,answer);
for(int i = 0; i < answer.length(); i++) {
if(answer[i] == ' ' || answer[i] == ':') {
continue;
}
if (isdigit(answer[i]) == false) {
cout << "Token = " << answer[i];
int operand2 = mystack.top();
mystack.pop();
int operand1 = mystack.top();
mystack.pop();
cout << " Pop " << operand2 << " Pop " << operand1;
if(answer[i] == '+') { //operation statements
result = operand1 + operand2;
}
else if(answer[i] == '-') {
result = operand1 - operand2;
}
else if(answer[i] == '*') {
result = operand1 * operand2;
}
else if(answer[i] == '/') {
result = operand1 / operand2;
}
mystack.push(result); //result returns to stack
cout << " Push " << result << endl;
}
else if(isdigit(answer[i]) == true){
int operand = 0;
while(i < answer.length() && isdigit(answer[i]) == true) {
operand = (operand*10) + (answer[i] - '0');
i++;
}
i--;
mystack.push(operand);
cout << "Token = " << operand << " Push " << operand << endl;
}
}
cout << "Token = Pop " << mystack.top() << endl << endl;
mystack.pop();
cout << "type 'Y' or 'y' to continue or type any other letter to quit: ";
getline(cin, done);
}
}
这里有一个简单的解决方法。此版本使用 int 并使用字符串堆栈。通过在整个文件中将 int
替换为 double
,这可以很容易地转换为双打,
这使用 getline() 和 istringstream 来解析输入。
它还使用字符串流将数字转换为字符串并返回。
从每一行解析多个单词时必须小心。此代码将输入行重定向到 ss,一个 istringstream 对象,然后从该对象中获取标记。
此外,如果您键入“s”,这将打印堆栈。
最后,您可以用一系列 space 分隔的数字任意加载堆栈,或者您可以一次输入一个数字。输入运算符时使用堆栈。
#include <iostream>
#include <stack>
#include <string>
#include <sstream>
///////////////////////
/// top_and_pop()
/// Save the top value from a stack, and then pop the stack
/// If the stack is empty, return the string "0".
/// If the stack was not empty, return the popped element.
std::string top_and_pop(std::stack<std::string> &stack)
{
std::string return_string;
if (stack.empty()) {
return_string = "0";
std::cout << "Stack Empty, returning 0" << std::endl;
} else {
return_string = stack.top();
std::cout << "Popping " << return_string << std::endl;
stack.pop();
}
return return_string;
}
//////////////////////
/// is_number
/// Parse number into a int using std::stringstream.
/// If successful, then, the stringstream will be empty.
/// Return: true if the str would successfully parse as a int
bool is_number(const std::string &str)
{
std::istringstream ss(str);
int number;
ss >> number;
if (!ss.fail() && ss.eof())
return true;
ss >> std::ws; // not needed in this program, because we already parsed the
// input to a single word without whitespace. Needed for parsing a single line
// that may contain any set of chars.
return !ss.fail() && ss.eof();
}
/////////////////////
/// is_operator
/// return false if str is not a single character or if an operator is not found
/// acceptable operators are anyof "+-*/"
bool is_operator(const std::string &str)
{
return (str.length() == 1 &&
str.find_first_not_of("+-*/") == std::string::npos);
}
/////////////////////
/// string_to_int
/// convert string to int
/// Check to be sure string can convert to a int before calling
/// if conversion fails, return 0;
int string_to_int(const std::string &str)
{
std::stringstream stream;
int number = 0;
stream << str;
stream >> number;
return number;
}
//////////////////////
/// stack_to_string
///
/// print elements of stack
std::string stack_to_string(std::stack<std::string> stack)
{
std::string return_string;
while (!stack.empty()) {
return_string += stack.top() + " ";
stack.pop();
}
return return_string;
}
int main()
{
std::stack<std::string> mystack;
std::string input_line;
bool done = false; /// flag to indicate that calcualtor is closing
std::string token_str;
int operand1, operand2, result;
std::cout
<< "Please enter an RPN expression. Expression may consist of any \n"
"combination of space-separated numbers or operators.\n"
"Operators may include '+', '-', '*', '/'. The stack is initialized\n"
"with an unlimited supply of zeroes.\n\n"
"Type 's' to print the current stack.\n"
"To exit, type a 'y'" << std::endl;
do {
getline(std::cin, input_line);
std::stringstream ss(input_line);
/// loop through all tokens in this input line
while (ss >> token_str) {
// Only numbers are allowed on the stack.
// If the current token is a number, push it on the stack as a string
if (is_number(token_str)) {
mystack.push(token_str);
} else if (is_operator(token_str)) {
operand2 = (int) string_to_int(top_and_pop(mystack));
operand1 = (int) string_to_int(top_and_pop(mystack));
// switch does not accept string as a type, and we checked to ensure
// it is a single character operand that is handled in the switch
switch (token_str[0]) {
case '+':result = operand1 + operand2;
break;
case '-':result = operand1 - operand2;
break;
case '*':result = operand1 * operand2;
break;
case '/':
if (operand2 == 0) {
std::cout << "Error: Cannot divide by zero" << std::endl;
continue; // don't push result, take new input.
} else {
result = operand1 / operand2;
}
break;
// default case not needed as we already checked operator, but
// for error checking, we include it
default:std::cout << "Operator not found" << std::endl;
continue;
}
mystack.push(std::to_string(result));
std::cout << " Push result " << result << " " << std::endl;
} else if ("Y" == token_str || "y" == token_str) {
done = true;
} else if ("stack" == token_str || "s" == token_str) {
std::cout << "stack: ";
std::string stack_dump = stack_to_string(mystack);
std::cout << stack_dump << std::endl;
} else {
std::cout << "Invalid input." << std::endl;
}
}
}
while (!done);
}