0

我有一个相当复杂的计算器,当用户输入“;”时会打印输出 (并按回车键。)我现在要做的是允许用户在按回车键时打印输出,(不使用分号。)我需要知道如何实现这一点。

旁注:计算器使用标记化来读取用户输入

这是计算器源代码的一部分,也是唯一需要更改的部分。它是 Token_stream 的成员函数,当计算器的各种其他函数调用以获取下一个令牌时调用它。

const char let = '#';
const char quit = 'Q';
const char print = ';';
const char number = '8';
const char name = 'a';
const char sq_rt = '@';
const char power = '^';
const char constant = '~';

Token Token_stream::get()
{
    if (full) { full=false; return buffer; }
    char ch;
    cin >> ch;
    switch (ch) {
    case '(':
    case ')':
    case '+':
    case '-':
    case '*':
    case '/':
    case '%':
    case ';':
    case '=':
    case ',':
    case constant:
    case power:
    case sq_rt:
    case let:
    case quit:
    case name:
        return Token(ch);   // let each character represent itself
    case '.':
    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':
    {   cin.unget();       // equivalent of putback
        double val;
        cin >> val;
        return Token(number,val);
    }
    default:
        if (isalpha(ch)) {       // in order to create variable names
            string s;
            s += ch;
            while(cin.get(ch) && (isalpha(ch) || isdigit(ch) || ch == '_')) s += ch;
            cin.unget();
            if (s == "const") return Token(constant);
            if (s == "quit") return Token(quit);
            if (s == "pow") return Token(power);
            if (s == "sqrt") return Token(sq_rt);
            if (s == "let") return Token(let);  
            if (s == "name") return Token(name);
            return Token(name,s);
             }
       else if (isspace(ch)) {    // my attempt at allowing enter to produce output
            string s;
            cin.get(ch);
            s += ch;
            if(s == "\n") return Token(print);
            }

            }
        error("Bad token");
    }

到目前为止,如果用户输入 5*5 并点击空格然后输入..没有任何反应。但是,如果他们点击空格,然后输入一个随机字符(任何字符,而不仅仅是 ;)然后按 Enter,它就会输出答案。在此之后,用户可以使用 enter 产生输出,但是它保存了用户在敲击空格后输入的额外令牌,因此操作顺序变得很混乱。

简而言之,我需要知道如何让用户最初点击空格然后输入(甚至只是输入,但现在使用空格并输入)以产生输出 - 没有任何额外的字符。

如果您想查看更多来源或对计算器本身有任何疑问以解决问题,我很乐意发布更多信息。

PS 原始程序来自我正在学习 C++ 的一本书。我一直在做一些改变它并为其添加功能的练习。

4

3 回答 3

2

我会先将该行读入字符串,然后将其传递给您的“令牌”类。

就像是:

#include <iostream>
#include <string>

...

{
    std::string in;
    getline( std::cin, in );
    Token t( in );
    // Do whatever you need to with 't'
    std::cout << in << " = " << t.Result() << std::endl;
}
于 2009-06-29T21:06:47.347 回答
0

扩展“厨房”

假设您像这样创建令牌流类:

int main()
{
     Token_stream    stream(std::cin);

     // Do Stuff.
};

你也可以改变这个:

int main()
{
    MyApplicationState   stateInfo;
    std::string          line;

    while(std::getline(std::cin,line))
    {
        std::stringstream s(line);
        Token_stream      stream(stateInfo,s);

        // Do stuff
    }
}

现在每一行都是它自己的流。
这假定每一行都包含表达式所需的所有信息,并且您可以将状态信息存储在对象 MyApplicationState 中。

于 2009-06-29T21:19:17.057 回答
0

扩展上述解决方案的另一个想法:

在一行不包含所有信息的情况下,即如果需要在多行上“空格”输入,则设置一个标准分隔字符。例如,两个换行符(连续两次输入)将标记流的结束。

然后只需将整个内容读入一个缓冲区(如之前的答案中建议的那样)并解析该缓冲区。

Windows 上的行尾通常是十六进制0X0D 0X0A序列。

于 2009-06-29T21:36:29.580 回答