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日

相关文章

  • json格式解析和libjson的用法介绍(关于cjson的使用方法)

    一、JSON格式解析简介 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。与XML类似,JSON也是一种无须定义复杂DTD(Data Type Definition,数据类型定义),就可直接使用的格式。由于其简明的格式、易于阅读等特性,得到了广泛的应用。 二、libjson的用法介绍 简介 libjson是一个C…

    C 2023年5月23日
    00
  • 华硕X550C怎么拆机 华硕X550C清理灰尘与升级SSD图文教程

    华硕X550C是一款经典的笔记本电脑,通常情况下使用时间长了之后就会出现散热问题或者存储容量不足的问题。为了解决这些问题,我们需要拆卸笔记本电脑并进行清理灰尘或者升级SSD。下面我将为大家提供华硕X550C拆机、清理灰尘以及升级SSD的详细攻略。 步骤一:准备工作 首先,我们需要准备以下材料: 十字螺丝刀 塑料卡片 SSD硬盘 硬盘盒 硅脂 清洁剂 清理刷 …

    C 2023年5月23日
    00
  • 2048小游戏C语言实现代码

    首先,2048小游戏是一款经典的益智游戏,玩家需要通过合并数字达到2048的目标。对于C语言实现,代码可以分为几个部分:界面显示、随机数字生成、输入处理、数字移动和合并、判断游戏是否结束。 界面显示 为了在终端中显示2048的游戏界面,我们需要使用C语言的库函数ncurses。首先,需要安装ncurses库,在Ubuntu系统下使用以下命令安装: sudo …

    C 2023年5月24日
    00
  • 解析JSON对象与字符串之间的相互转换

    解析JSON对象与字符串之间的相互转换是在前端开发中非常常见的操作之一。这里提供一份完整的攻略,帮助你轻松实现JSON对象与字符串之间的相互转换。 解析JSON对象 在JavaScript中,解析JSON对象需要使用到JSON.parse()方法。该方法可以将JSON格式的字符串转换为JavaScript对象。下面是一个示例: var jsonStr = ‘…

    C 2023年5月23日
    00
  • 解决@Transactional注解事务不回滚不起作用的问题

    解决@Transactional注解事务不回滚不起作用的问题的详细攻略如下: 问题描述 在进行数据库操作时,我们通常会使用@Transactional注解来保证事务的原子性,但在使用过程中可能会出现事务不回滚不起作用的问题,导致数据一旦出现异常就无法恢复。这种情况通常是因为注解失效或者配置不正确导致的。 解决方案 1. 配置文件中开启事务管理器 我们可以在配…

    C 2023年5月23日
    00
  • BF算法的实现:病毒感染检测

    一、问题引入 BF(Brute-Force)算法介绍了BF算法的具体实现,但并未结合具体案例。 本随笔就是结合案例(病毒感染检测)对BF算法进行结合分析。 案例4.1: 病毒感染检测 医学研究者最近发现了某些新病毒, 通过对这些病毒的分析, 得知它们的 DNA 序列都是环状的。现在研究者巳收集了大量的病毒DNA 和人的DNA 数据,想快速检测出这些人是否感染…

    C语言 2023年4月17日
    00
  • c病毒程序原理分析(防范病毒 c语言小病毒示例)

    这篇文章主要是讲解如何防范病毒及 c 语言小病毒示例,文章中包含两条示例说明。 标题 C 病毒程序原理分析 正文 病毒是计算机领域中的一种非常危险的电脑程序,可以通过复制自身的方式感染计算机,破坏计算机系统的正常运行。在这篇文章中,我们将简单介绍 C 病毒程序的原理以及如何防范此类病毒。 防范病毒 升级防病毒软件:使用强大的防病毒软件可以有效的保护计算机系统…

    C 2023年5月23日
    00
  • 新手向超详细的C语言实现动态顺序表

    当初步学习C语言之后,常常将动态内存管理作为初学者的第一个难点。本文将向新手讲解实现动态顺序表的过程,以及如何使用动态内存管理API来解决动态分配和释放内存的问题。本攻略使用C语言编写,通过动态分配内存的方式来模拟实现动态顺序表。 实现步骤 1. 定义数据结构 首先,需要定义一个结构体,来表示这个动态顺序表的数据结构。结构体中至少需要包含如下信息:- 存储元…

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