2009-06-29 47 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序列。