2016-01-22 133 views
0

我想在C中創建一個計算器。我的積極,我的參數(字符*字符串)在我的eval函數是正確的,但我不明白爲什麼或如何正確使用它。我的eval函數將以postfix表示法的形式輸入數學表達式。所以這裏是我的代碼到目前爲止,基本上我試圖接受一個字符串,將所有數字推入一個字符串堆棧,然後如果找到一個運算符,從字符串堆棧彈出兩個「字符串」,將這些字符串轉換爲整數這是我不確定如何做的另一件事),做計算,將結果推送到int stack。在搜索完所有輸入後,循環遍歷整個堆棧並添加所有的整數。這裏是我的代碼:(忽略包括)/ *如何在C中使用char *的字符進行循環?

int eval(char* String); //implicit declarations 
int bourneLongPush(int); 
char* bournePop(void); 
int bournePush(char *string); 
int bourneLongPop(void); 
int bourneGetLongStackSize(void); 

int eval(char* String) 
{ 
    int result = 0; 
    int index = 0; 
    int arg1; 
    int arg2; 
    char* endptr; 

    while(String[index] != '\0'){      //while our  String pointer is not equal to null, 
     if(strtoimax(String, &endptr, 10) == NULL){ //if the character isn't a number, 
      switch(String[index]){      //switch on the operator 
      case "+": 
       arg2 = bournePop(); 
       arg1 = bournePop();//*** how do I change char*'s to ints? 
       bourneLongPush(arg2+arg1); 
       break; 
      case "-": 
       arg2 = bournePop(); 
       arg1 = bournePop(); 
       bourneLongPush(arg2-arg1); 
       break; 
      case "/": 
       arg2 = bournePop(); 
       arg1 = bournePop(); 
       bourneLongPush(arg2/arg1); 
       break; 
      case "*": 
       arg2 = bournePop(); 
       arg1 = bournePop(); 
       bourneLongPush(arg2*arg1); 
       break; 
      case ">": 
       arg2 = bournePop(); 
       arg1 = bournePop(); 
       bourneLongPush(arg2>>arg1); 
       break; 
      case "<": 
       arg2 = bournePop(); 
       arg1 = bournePop(); 
       bourneLongPush(arg2<<arg1); 
       break; 
      case "^": 
       arg2 = bournePop(); 
       arg1 = bournePop(); 
       bourneLongPush(pow(arg2, arg1)); 
       break; 
      case "|": 
       arg2 = bournePop(); 
       arg1 = bournePop(); 
       bourneLongPush(arg2|arg1); 
       break; 
      case "&": 
       arg2 = bournePop(); 
       arg1 = bournePop(); 
       bourneLongPush(arg2&arg1); 
       break; 
      case "%": 
       arg2 = bournePop(); 
       arg1 = bournePop(); 
       bourneLongPush(arg2%arg1); 
       break; 
      default: 
       break; 
     } 
     else{        //a number was found 
     int check = bournePush(String[index]);//push the number into string stack 
      if(check == 1) 
      { 
       //error in push due to size 
      } 
     } 
    index++; 
    } 
} 
//Our input was read in as null so no more input needs to be read 
    for(int j = 0; j<(int)bourneGetLongStackSize; j++) 
    { 
     int num = bourneLongPop(); 
     result += num; 
    } 
    return result; 
} 
+1

你不能移動'arg2 = bournePop(); arg1 = bournePop();'在'switch'語句之前? –

回答

1

所以,我建議,與其推動所有字符進棧,再後來將它們轉換爲整數和應用運營商,我們爲什麼不在將它們推入堆棧之前將它們轉換爲整數,然後應用操作員。

所以,你else條件的循環將是這個樣子::

int num = 0; 
while() { 
    if(the character isn't a number) { //I do not exactly understand the condition you used here, but I hope you have got it figured 
     bournePush(num); 
     num = 0; 
     switch(String[index]) { 
     ... 
     ... 
     //remains same 
     } 
    } 
    else { 
     convertToNum(num, string[index]); 
    } 
} 

這裏我用num存儲目前在串號的價值,所以說,如果我在字符串中遇到123我將使用convertToNum函數將int 123存儲在num中,所以當我碰到操作員時,我只需將堆棧中的完整num並重新初始化爲0,以便我可以使用它來存儲下一個數字。

而這正是convertToNum樣子::

void convertToNum(int &num, char digit) { 
    int numDigit = digit - '0'; 
    num = num*10 + numDigit; 
} 

嗯,這會回答你如何轉換的字符爲整數的問題。這裏我通過num作爲參考,以便我在converToNum中所做的任何更改也在main中看到。然後在numDigit我從digit減去char0這將從char digit減去char 0的ASCII值,並將給我們由該字符表示的整數的值。然後我用10做一個簡單的乘法運算並添加下一個數字,只是簡單的數學運算。

此外,這非常簡化了bournePopborneLongPop函數,因爲現在你的堆棧只是整數,所以你不需要分開函數,現在你只需從堆棧中彈出一個值並將其與在您的switch內部的運營商。

我希望這有助於!

編輯::

我假設你的後綴字符串有間獨立的象徵數字,空格,所以你可能確實有這樣的:

123 456 +

字符串

因此,上面的代碼實際上會失敗,因爲在456之後它將遇到空格,它將輸入if條件,並且p ush 456進入堆棧,然後當它會打到+它會將0推入堆棧,然後在0 and 456上應用+這是錯誤的,所以我們在num這個堆棧中只有當我們遇到空間時纔會這樣。因此,最終的代碼要仰望這樣的:

int num = 0; 
while() { 
    if(the character isn't a number) { //I do not exactly understand the condition you used here, but I hope you have got it figured 
     if(String[index] == ' ') { 
      bournePush(num); 
      num = 0; 
     } else { 
      switch(String[index]) { 
      ... 
      ... 
      //remains same 
      } 
     } 
    } 
    else { 
     convertToNum(num, string[index]); 
    } 
} 

而且我完全不認爲你會switch工作,因爲當你寫switch(String[index])您爲char定義的switch當你寫case "+"您所定義的作爲一個字符串的情況,我認爲這會給編譯錯誤。所以,你所有的case應該像這樣改變case '+',這將工作。

而且一個簡單的方法來檢查,如果一個字符是數字還是不應該是這樣::

int checkNum(char a) { 
    if(a >= '0' && a <= '9') 
     return 0; 
    return 1; 
} 

此檢查,如果a09之間,並返回0(假)和1(真)否則,只是建議!

1

1)if(strtoimax(String, &endptr, 10) == NULL){不是一個很好的測試,看看轉換是否奏效。

intmax_t value = strtoimax(String, &endptr, 10); 
if (endptr != String) { 
    // endptr now points to the next part of the string to parse 
    ConversionWorked(value); 
} else 
    ConversionFailed(); 
} 

代碼可以清除errno檢測溢出

errno = 0; 
intmax_t = value = strtoimax(String, &endptr, 10); 
if (endptr != String) { 
    if (errno) ConversionOverflowed(value) 
    else ConversionWorked(value); 
} else 
    ConversionFailed(); 
} 

2)錯誤switch()使用

switch(String[index]) { 
    // case "+": 
    case '+': // String[index] is a `char`, not a string 

3)可能的其他問題,如bournePush() - 但需要看到的未發佈代碼來解決。