2009-06-29 43 views
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和命中空间,然后进入......没有任何事情发生。然而,如果他们击中空间,则输入一个随机字符(任何字符,而不仅仅是;)然后按回车键,输出答案。在此之后,用户可以使用回车来产生输出,但是它保存了用户在输入空间后输入的额外令牌,所以操作顺序变得棘手。

总之,我需要知道如何让用户最初点击空间,然后输入(甚至只是输入,但使用空间并现在输入)来产生输出 - 不需要任何额外的字符。

如果您希望查看更多来源或有任何有关计算器本身的问题以解决问题,我很乐意发布更多内容。

P.S.原始程序来自我正在学习C++的书。我刚刚做了一些改变它并添加功能的练习。

回答

2

我会先将行读入字符串,然后将其传递给您的'Token'类。

喜欢的东西:

#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; 
} 
0

Exapnding在 '厨房'

假设你创建你这样的标记流类:

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中。

0

另一个想法,扩大对上述解决方案:

在这种情况下是一个行不包含所有的信息,即如果有需要“空间”在多个线路输入设定一个标准划定字符(多个)。 例如,两条换行符(连续输入两个)将标记流的结束。

然后,只需将整个事物读入一个缓冲区(就像之前的答案中所述)并解析该缓冲区。

在Windows上行结束通常是或十六进制0X0D 0X0A序列。