当我们实现一个简单的计算器功能时,需要考虑以下几个方面:
- 用户输入的合法性检查
- 进行算术运算的函数实现
- 错误处理和提示信息输出
第一步,我们需要先获取用户输入的表达式,并对其进行合法性检查。用户输入的表达式应该是一个合法的算术表达式,不能含有非法字符,比如字母等。我们可以使用正则表达式来判断用户输入的内容是否合法。
示例1:
#include <regex.h>
bool is_valid_input(char *input) {
regex_t reg;
int reti = regcomp(®, "[0-9+/*%-]+", REG_EXTENDED);
if (reti) return false;
int match = regexec(®, input, 0, NULL, 0);
regfree(®);
if (match != 0) return false;
return true;
}
在上面的示例中,我们使用了POSIX的正则表达式库(regex.h)来编写正则表达式判断用户输入的内容是否是合法的算术表达式。如果不是,我们会返回false,表示用户的输入有误。
第二步,我们需要实现进行算术运算的函数。我们需要把用户输入的表达式转换成可计算的形式,再进行运算。在这里,我们可以使用栈来对表达式求解。
示例2:
#include<stdlib.h>
#include<stdio.h>
#include<ctype.h>
#include<string.h>
#define size 50
double s[size];
int top1=-1,top2=-1;
char op[size];
void error(char* s,int l) {
printf("\n%s",s);
for(int i=0;i<=l;i++) printf("%c",op[i]);
exit(0);
}
void push_num(double x) {
if(top1==size)error("plan1 stack is full",top1);
s[++top1]=x;
}
void push_op(char ch) {
if (top2 == size)error("plan2 stack is full",top1);
if (ch == ')') {
while (op[top2] != '(') {
double b = s[top1];
top1--;
double a = s[top1];
top1--;
char c = op[top2];
top2--;
if (a >= -1e-8 && a <= 1e-8 && c == '/') error("divided by zero",top1);
switch (c) {
case '+':push_num(a + b); break;
case '-':push_num(a - b); break;
case '*':push_num(a * b); break;
case '/':push_num(a / b); break;
case '%':push_num((int)a % (int)b); break;
default: error("illegal character in stack", top1);
}
}
top2--;
return;
}
if (ch == '+' || ch == '-') {
while (top2 >= 0 && op[top2] != '(') {
char c = op[top2];
double b = s[top1];
top1--;
double a = s[top1];
top1--;
top2--;
if (a >= -1e-8 && a <= 1e-8 && c == '/') error("divided by zero",top1);
switch (c) {
case '+':push_num(a + b); break;
case '-':push_num(a - b); break;
case '*':push_num(a * b); break;
case '/':push_num(a / b); break;
case '%':push_num((int)a % (int)b); break;
default: error("illegal character in stack", top1);
}
}
op[++top2] = ch;
return;
}
if (ch == '*' || ch == '/' || ch == '%') {
while (top2 >= 0 && op[top2] != ')' && op[top2] != '+' && op[top2] != '-') {
char c = op[top2];
double b = s[top1];
top1--;
double a = s[top1];
top1--;
top2--;
if (a >= -1e-8 && a <= 1e-8 && c == '/') error("divided by zero",top1);
switch (c) {
case '+':push_num(a + b); break;
case '-':push_num(a - b); break;
case '*':push_num(a * b); break;
case '/':push_num(a / b); break;
case '%':push_num((int)a % (int)b); break;
default: error("illegal character in stack", top1);
}
}
op[++top2] = ch;
return;
}
if (ch == '(') { op[++top2] = '('; return; }
error("illegal character", top1);
}
double calculate(char* input) {
int l = strlen(input);
input[l] = ')';
for (int i = 0; i < l; i++) {
if (input[i] == ' ')continue;
if (isdigit(input[i])) {
char num[20] = { '\0' };
int k = 0;
while (isdigit(input[i]) || input[i] == '.') {
num[k++] = input[i++];
}
i--;
push_num(atof(num));
}
else push_op(input[i]);
}
while (top2 >= 0) {
double b = s[top1];
top1--;
double a = s[top1];
top1--;
char c = op[top2];
top2--;
if (a >= -1e-8 && a <= 1e-8 && c == '/') error("divided by zero", top1);
switch (c) {
case '+':push_num(a + b); break;
case '-':push_num(a - b); break;
case '*':push_num(a * b); break;
case '/':push_num(a / b); break;
case '%':push_num((int)a % (int)b); break;
default: error("illegal character in stack", top1);
}
}
return s[top1];
}
上面的示例是一个迭代版的栈计算器,它使用两个栈来处理数字和操作符,并在处理好操作符后返回计算结果。需要注意的是,在实现中,我们还需要考虑一些特殊情况,比如除数为0等异常情况。
第三步,我们需要考虑如何处理错误和输出提示信息。当用户输入有误或者计算过程中发生了异常情况,我们需要及时返回错误信息给用户,让用户重新输入或者纠正错误。同时,我们还需要在计算完成之后,通过合适的方式将结果输出给用户。
以上三个步骤完成后,我们就可以得到一个完整的简单计算器。除此之外,我们还可以加入一些额外的特性,比如表达式的优先级处理等。这样,我们就可以得到一个更加完备的计算器。
示例3:
int main() {
char input[100];
printf("输入表达式:");
scanf_s("%[^\n]",input,99);
if (!is_valid_input(input)) {
printf("输入有误\n");
return 0;
}
printf("结果是:%.2f\n", calculate(input));
return 0;
}
在上面的示例中,我们通过获取用户输入,并对其进行合法性检查和计算,最后输出计算结果。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C语言实现简单计算器功能(2) - Python技术站