我必须在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;
}
答案 0 :(得分:1)
您可以使用前缀符号来简化计算。
您有很多在线材料和中缀前缀表示法代码。
基本思想是可以将表示前缀表示法的输入(例如:(1 + 2)*(3 * 4))转换为前缀表示法(* + 12 * 34)。使用堆栈数据结构来计算给定的前缀结构。
EVALUATE_PREFIX(STRING):
因此,假设您拥有: * + 12 * 34 ,就像我们上一个示例一样。
我建议您看一下前缀,中缀和后缀表达式。很快就会了解它,它应该为您的问题提供一个很好的解决方案。希望能帮助到你。 :)
答案 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;
}