C语言实现简单计算器功能(2)

当我们实现一个简单的计算器功能时,需要考虑以下几个方面:

  1. 用户输入的合法性检查
  2. 进行算术运算的函数实现
  3. 错误处理和提示信息输出

第一步,我们需要先获取用户输入的表达式,并对其进行合法性检查。用户输入的表达式应该是一个合法的算术表达式,不能含有非法字符,比如字母等。我们可以使用正则表达式来判断用户输入的内容是否合法。

示例1:

#include <regex.h>

bool is_valid_input(char *input) {
    regex_t reg;
    int reti = regcomp(&reg, "[0-9+/*%-]+", REG_EXTENDED);
    if (reti) return false;
    int match = regexec(&reg, input, 0, NULL, 0);
    regfree(&reg);
    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技术站

(0)
上一篇 2023年5月23日
下一篇 2023年5月23日

相关文章

  • C语言实现推箱子游戏的代码示例

    很高兴为你介绍如何用C语言实现推箱子游戏的代码示例。推箱子游戏是一款经典的益智游戏,通过在有限空间内推动箱子达到目标位置,考验玩家的空间思维和逻辑思维。下面详细讲解实现该游戏的完整攻略。 环境搭建 在开始Coding之前,首先需要在本地计算机上安装C语言开发环境,如IDE(集成开发环境)、编译器等。推荐使用Visual Studio Code(简称VS Co…

    C 2023年5月24日
    00
  • C语言中如何进行代码重用?

    在 C 语言中,可以使用函数来实现代码重用。函数是一段可重用的代码块,它可以接收参数,执行一定的操作,然后返回结果。 以下是 C 语言中实现代码重用的步骤: 定义函数:使用 function_name() 关键字定义一个函数,并在花括号中输入函数操作的代码。 函数参数:在函数括号中可以定义函数参数,用于传递数据或变量。可以使用参数的默认值或者变量的地址来传递…

    C 2023年4月27日
    00
  • C语言分支循环其嵌套语句的使用

    对于C语言程序,分支和循环结构都是非常重要的控制结构。它们可以让程序根据条件执行不同的操作,并可以利用循环结构让重复的操作更加简单和高效。 在实际编程中,分支和循环结构的嵌套使用能够更好地解决实际问题。下面我们分别讲解分支和循环在嵌套结构中的使用方法。 分支结构的嵌套使用 分支结构通常使用if / else或switch / case语句完成。分支结构的嵌套…

    C 2023年5月30日
    00
  • c++ 动态内存分配相关总结

    C++ 动态内存分配相关总结 C++ 中的动态内存分配是通过 new 和 delete 进行的,它们可以用来在程序运行时分配和释放内存。相比于静态内存分配,它具有更高的灵活性和可扩展性。 动态内存分配的基本使用 分配动态内存 new 运算符可以分配指定大小的动态内存,返回的是分配内存的首地址,需要通过指针接收: // 分配一个 int 类型的动态数组 int…

    C 2023年5月23日
    00
  • C语言学生成绩管理系统课程设计word版

    针对“C语言学生成绩管理系统课程设计word版”的完整攻略,我将从以下几个方面进行讲解: 1.系统需求分析2.系统设计方案3.系统开发实现4.系统测试与维护 1.系统需求分析 在进行任何系统开发之前,必须清楚自己的需求,包括用户的需求和技术的需求,了解系统功能、数据存储和处理方式、用户交互等方面的要求。对于此次课程设计,针对学生成绩管理系统,我们需要考虑以下…

    C 2023年5月22日
    00
  • C连接Mysql数据库代码

    当我们需要在C程序中使用MySQL数据库时,我们需要连接MySQL数据库。下面是将C程序连接MySQL数据库的完整攻略。 步骤1:安装MySQL C API 在C程序中使用MySQL数据库,我们需要安装MySQL C API。MySQL提供了C API开发包,我们可以到MySQL官方网站上下载。 步骤2:连接MySQL数据库 连接MySQL数据库前,需要先初…

    C 2023年5月23日
    00
  • C++ 动态内存管理详情解说

    C++ 动态内存管理详情解说 在 C++ 程序中,动态内存管理是一项非常重要的任务。动态内存分配和释放可以在运行时动态地完成,使程序具有更大的灵活性。本文将详细解释动态内存管理的概念以及它的使用方法。 什么是动态内存? 动态内存是指程序在运行时动态地分配的内存。每个程序都有一个静态内存,该内存是编译时分配的。静态内存的大小是固定的,而动态内存的大小不是固定的…

    C 2023年5月22日
    00
  • C++中的异常实例详解

    C++中的异常实例详解 异常是C++中处理错误的一种机制。当程序运行时发生错误,可以抛出一个异常,并且在需要处理异常的地方捕获该异常。本文将详细介绍异常的使用以及异常相关的概念。 抛出异常 throw语句 C++中,可以通过throw语句抛出异常,例如: throw "Something went wrong."; 上述语句抛出了一个ch…

    C 2023年5月23日
    00
合作推广
合作推广
分享本页
返回顶部