用c做计算器,如何计算两个以上的数字

时间:2019-01-02 13:09:14

标签: c

我必须在c中制作一个计算器,该程序在其中的第一行中读取数学运算,然后在下一行中打印其结果。如果在数学运算中使用的字符不是数字,则还必须写入错误消息。现在,我的程序只读取一行中的一项数学运算(例如2 + 5)。有什么想法可以在一行中读取更多操作吗? (例如2 + 5 + 7 + 8) 我的代码如下:

#include <stdio.h>

int main(void) {
    int ch;
    int input1 = 0, input2 = 0, flag = 0, flag1 = 0;
    char oper;
    int i = 1;
    while ((ch = getchar()) != EOF){
        int result = 0;
        if (ch != '\n'){ /* If user didnt change line */
            if (ch >= '0' && ch <= '9'){ /* Checks if ch is a number */
                if(flag == 0) /* flag is used to change to the second number */
                    input1 = input1*10 + ch - '0'; /* Converts ASCII to decimal */
                else
                    input2 = input2*10 + ch - '0';  /* Converts ASCII to decimal*/
            }
            if (ch == '+' || ch == '-' || ch == '*'){ /* Operator has been detected */
                oper = ch;
                flag = 1;
            }
            if (ch >= 'A'){
                flag1 = 1; /* flag1 is used to determine if a non-number character was written */
            }   
        }
        else{
            switch(oper){
                case '+': /* if operator is "+" add the numbers */
                    result = input1 + input2;
                break;
                case '-': /* if operator is "-" subtract the numbers */
                    result = input1 - input2;
                break;
                case '*': /* if operator is "*" multiply the numbers */
                    result = input1 * input2;
                break;      
            }
            if (flag1 == 0){
                printf("Result %d: %d\n", i, result);
                i++;
                input1 = 0;
                input2 = 0;
                flag = 0;
            }
            else if (flag1 == 1){
                printf("Result %d: Error!\n", i);
                i++;
                input1 = 0;
                input2 = 0;
                flag = 0;
                flag1 = 0;
            }
        }
    }
    return 0;
}

2 个答案:

答案 0 :(得分:1)

您可以使用前缀符号来简化计算。
您有很多在线材料和中缀前缀表示法代码。
基本思想是可以将表示前缀表示法的输入(例如:(1 + 2)*(3 * 4))转换为前缀表示法(* + 12 * 34)。使用堆栈数据结构来计算给定的前缀结构。

EVALUATE_PREFIX(STRING):

因此,假设您拥有: * + 12 * 34 ,就像我们上一个示例一样。

  1. 在表达式的末尾放置一个指针,使其在我们的示例中指向数字4,然后读取该字符。
  2. 如果指针处的字符是操作数,则将其推入堆栈。
  3. 如果指针处的字符是运算符,则从堆栈中弹出两个元素。根据操作员的意见,对这些元素进行操作,然后将结果推回堆栈。
  4. 将指针递减1并转到2。只要表达式中还有要扫描的字符,就执行步骤。
  5. 如果没有更多的字符了,结果将存储在堆栈的顶部,因此只需将其返回即可。

我建议您看一下前缀,中缀和后缀表达式。很快就会了解它,它应该为您的问题提供一个很好的解决方案。希望能帮助到你。 :)

答案 1 :(得分:1)

我发现这对我自己是一个很好的锻炼= D 建议:

  • 状态机可以帮助获取输入
  • 在这种情况下(计算器),链接列表应足以促进多项操作
  • 在收集输入内容时填写列表,然后按照操作员优先级的顺序清空列表

我尝试整理一些代码,希望对您有所帮助。虽然还没有机会进行编译和测试。

 #include <stdio.h>
 #include <stdlib.h>

#define MAX_INPUT_SIZE 1000;
struct Node
{
    char operator;
    int result;
    struct Node* left;
    struct Node* right;
};

enum InputState{
    START = 0,
    NUMBER,
    OPERATOR
    };

void pushNodeToList( struct Node**head, struct Node**tail, char op, int result)
{
    struct Node* nodePtr = malloc(sizeof(*nodePtr));
    nodePtr->operator = op;
    result = result;
    if(!head)
    {
        *head = nodePtr;
        *tail = nodePtr;
        nodePtr->left = 0;
        nodePtr->right = 0;
    }
    else{
        nodePtr->left = *tail;
        (*tail)->right = nodePtr;
        *tail = nodePtr;
    }
}

void calculateNode( struct Node* nodePtr)
{
    if(nodePtr->left != 0 && nodePtr->right != 0)
    {
        if(nodePtr->left->operator == 'n' && nodePtr->right->operator == 'n' )
        {
            //calculate result
            switch(nodePtr->operator)
            {
                case '+':
                    nodePtr->result = nodePtr->left->result + nodePtr->right->result;
                    break;
                case '-':
                    nodePtr->result = nodePtr->left->result - nodePtr->right->result;
                    break;
                case '*':
                    nodePtr->result = nodePtr->left->result * nodePtr->right->result;
                    break;
                default:
                    printf("Calculation Error: %d \n", 5);
                    return;

            }
            //change type of node to 'n'
            nodePtr->operator == 'n';

            //reduce the numbers consumed
            struct Node* tempLeft = nodePtr->left;
            struct Node* tempRight = nodePtr->right;
            nodePtr->left = tempLeft->left;
            nodePtr->right = tempRight->right;
            free(tempLeft);
            free(tempRight);
        }
        else
        {
            printf("Calculation Error: %d \n", 4);
            return;
        }
    }
    else{
        printf("Calculation Error: %d \n", 3);
        return;
    }
}

int main(void) {

int ch;
struct Node* head = 0;
struct Node* tail = 0;

//have a state machine to handle the logics related to parsing input
int num = 0;
enum InputState mState = START;

int i = 1;
while ((ch = getchar()) != EOF)
{
    switch(mState)
    {
        case START:
            if (ch >= '0' && ch <= '9'){
                mState = NUMBER;
                num = 0;
                //initialize state to number
            }
            else if(ch == '+' || ch == '-' || ch == '*'){
                mState = OPERATOR;
                //initilize state to operator
            }
            else{
                //your error code
                printf("Input Error: %d \n", 1);
                return 0;
            }
        break;
        case NUMBER:
            if (ch >= '0' && ch <= '9'){
                num = num * 10 + ch - '0';
            }
            else if(ch == '+' || ch == '-' || ch == '*'){
                mState = OPERATOR;
                //we just got a number recorded
                pushNodeToList(&head,&tail,'n',num);//'n' for number
            }
            else{
                printf("Input Error: %d \n", 2);
                return 0;
            }
        break;
        case OPERATOR:
            if (ch >= '0' && ch <= '9'){
                mState = NUMBER;
                num = ch - '0';
            }
            else if(ch == '+' || ch == '-' || ch == '*'){
                pushNodeToList(&head,&tail,ch,0);//push in operator
            }
            else{
                printf("Input Error: %d \n", 3);
                return 0;
            }
        break;
    }
}
//terminal condition to push-in last number
if(mState == NUMBER)
{
    pushNodeToList(&head,&tail,'n',num);//'n' for number
}

//higher prioriety operation
struct Node* workingPtr = head;
while(workingPtr !=tail)//assuming the last input is number (not operator)
{
    if(workingPtr->operator == '*')
    {
        calculateNode(workingPtr);
    }
}
//lower prioriety operations
workingPtr = head;
while(workingPtr !=tail)
{
    if(workingPtr->operator == '+' || workingPtr->operator == '-' )
    {
        calculateNode(workingPtr);
    }
}
//print result
if(head == tail && head->operator == 'n')
{
    printf("Result : %d\n", head->result);
}
else
{
    printf("Error: %d \n", 7);
    return 0;
}


return 0;
}