我是一个新手,试图解决Stroustrup的PPP第6章中的练习。除了"X"one_answers"X",一切都很好。我输入后跟'='的表达式并收到正确的结果,但是当我点击'X'或'X'退出程序时,我收到错误' ' primary expected ' '。你知道我错过了什么吗?我使用GCC 8.3.0, VS Code和'g++ -o nameofexecutable.exe sourcfile .cpp'来编译。我也用windows 10。下面是我的代码:
#include "std_lib_facilities.h"
class Token {
public:
char kind;
double value;
Token(char ch)
:kind(ch), value(0) { }
Token(char ch, double val)
:kind(ch), value(val) { }
};
class Token_stream {
public:
Token_stream();
Token get();
void putback(Token t);
private:
bool full;
Token buffer;
};
// The constructor just sets full to indicate that the buffer is empty:
Token_stream::Token_stream()
:full(false), buffer(0)
{}
// The putback() member function puts its argument back into the Token_stream's buffer:
void Token_stream::putback(Token t){
if (full) error("putback() into a full buffer");
buffer = t;
full = true;
}
Token Token_stream::get(){
if (full) {
full=false;
return buffer;
}
char ch;
cin >> ch;
switch (ch) {
case '=':
case 'x': // for "quit" it does not work!
case 'X': // for "quit" it does not work!
case '(': case ')': case '+': case '-': case '*': case '/': case '%':
return Token(ch);
case '.':
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
{
cin.putback(ch);
double val;
cin >> val;
return Token('8',val);
}
default:
error("Bad token");
}
}
Token_stream ts;
double expression();
// deal with numbers and parentheses
double primary()
{
Token t = ts.get();
switch (t.kind) {
case '(':
{
double d = expression();
t = ts.get();
if (t.kind != ')') error("')' expected");
return d;
}
case '8': // '8' is used to represent a number
return t.value;
default:
error("primary expected");
}
}
// deal with *, /, and %
double term()
{
double left = primary();
Token t = ts.get();
while(true) {
switch (t.kind) {
case '*':
{
left *= primary();
t = ts.get();
break;
}
case '/':
{
double d = primary();
if (d == 0) error("divide by zero");
left /= d;
t = ts.get();
break;
}
case '%':
{
int d = primary();
int l = left;
if (d == 0) error("divide by zero");
left = l%d;
t = ts.get();
break;
}
default:
ts.putback(t);
return left;
}
}
}
// deal with + and -
double expression()
{
double left = term();
Token t = ts.get();
while(true) {
switch(t.kind) {
case '+':
left += term();
t = ts.get();
break;
case '-':
left += term();
t = ts.get();
break;
default:
ts.putback(t);
return left;
}
}
}
int main()
try
{
cout << "A simple calculator"<<endl;
cout << "Floating point numbers are acepted"<<endl;
cout << "You can use: '+','-','*','/', and '%'" << endl;
cout << "Enter X or x to quit" << endl;
cout << "Use '=' to solve" << endl;
double val;
while (cin) {
Token t = ts.get();
if (t.kind == 'x') break; // 'q' for quit
if (t.kind == '=') // ';' for "print now"
cout << "=" << val << 'n';
else
ts.putback(t);
val = expression();
}
keep_window_open();
}
catch (exception& e) {
cerr << "error: " << e.what() << 'n';
keep_window_open();
return 1;
}
catch (...) {
cerr << "Oops: unknown exception!n";
keep_window_open();
return 2;
}
Padawan在使用switch/case
时需要了解break
语句break
防止从一个案例落到下一个案例:
char ch;
cin >> ch;
switch (ch) {
case '=':
// Do something for '=';
break; // exit the case
case 'x': // for "quit" it does not work!
case 'X': // for "quit" it does not work!
return 0; // exit from function.
// No need for break here since return breaks out of the switch.
case '(': case ')': case '+': case '-': case '*': case '/': case '%':
return Token(ch);
// No need for break here since return breaks out of the switch.
case '.':
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
{
cin.putback(ch);
double val;
cin >> val;
return Token('8',val);
}
// No need for break here since return breaks out of the switch.
default:
error("Bad token");
}