vs2022利用栈求表达式的值,语言都调过了就是练习一直都是乱码

img

求各位兄弟帮我看看,感谢


#include 
#include 
#include 
#include 
#include 
#include 
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
#define ERROR 0
#define OK 1
#pragma warning(disable:6385 6386)
//定义表达式
typedef struct shiti
{
    char a[20];
    long result;
}xuanti;
typedef struct SqStack1
{//建立数字栈
    int* base;
    int* top;
    int stacksize;
}SqStack1;
typedef struct SqStack2
{//建立运算符栈
    char* base;
    char* top;
    int stacksize;
}SqStack2;
void WriteToFile(xuanti* pstu, int num);
void ReadFromFile(xuanti* pstu, int num);
void page_title(char* menu_item)
{//建立菜单
    printf(">>>数进修题库<<<\n\n-%s-\n\n", menu_item);
}
void return_confirm()
{
    printf("\n按任意键返回……\n");
    int n=getchar();
}
void IntInitStack(SqStack1* S1)
{
    S1->base = (int*)malloc(STACK_INIT_SIZE * sizeof(int));
    if (!S1->base)
        exit(ERROR);
    S1->top = S1->base;
    S1->stacksize = STACK_INIT_SIZE;
}//IntInitStack
void CharInitStack(SqStack2* S2)
{
    S2->base = (char*)malloc(STACK_INIT_SIZE * sizeof(char));
    if (!S2->base)
        exit(ERROR);
    S2->top = S2->base;
    S2->stacksize = STACK_INIT_SIZE;
}//CharInitStack
long IntGetTop(SqStack1* S1)
{//取栈顶元素
    long e1;
    if ((*S1).top == (*S1).base)
        return 0;
    e1 = *((*S1).top - 1);
    return e1;
}//IntGetTop
char CharGetTop(SqStack2* S2)
{//取栈顶元素
    char e2;
    if ((*S2).top == (*S2).base) return 0;
    e2 = *((*S2).top - 1);
    return e2;
}//IntGetTop
int IntPush(SqStack1* S1, int e1)
{//入栈
    *(*S1).top++ = e1;
    return OK;    
}//IntPush
int CharPush(SqStack2* S2, char e2)
{//入栈
    *(*S2).top++ = e2;
    return OK;
}//CharPush
int IntPop(SqStack1* S1)
{//出栈
    int e1;
    if ((*S1).top == (*S1).base)
        return 0;
    e1 = *--(*S1).top;
    return e1;
}//IntPop
int CharPop(SqStack2* S2)
{//出栈
    char e2;
    if ((*S2).top == (*S2).base) return 0;
    e2 = *--(*S2).top;
    return e2;
}//CharPop
char Precede(char a, char b)
{
    int i, j;
    char Table[8][8] = { ' ','+','-','*','/','(',')','#',
                 '+','>','>','<','<','<','>','>',
                 '-','>','>','<','<','<','>','>',
                 '*','>','>','>','>','<','>','>',
                 '/','>','>','>','>','<','>','>',
                 '(','<','<','<','<','<','=',' ',
                 ')','>','>','>','>',' ','>','>',
                 '#','<','<','<','<','<',' ','=',
    };     //优先级表格
    for (i = 0; i < 8; i++)
        if (Table[0][i] == a)           //纵坐标寻觅
            break;
    for (j = 0; j < 8; j++)                    //横坐标寻觅
        if (Table[j][0] == b)
            break;
    return Table[j][i];
}//Precede
int Operate(int a, char theta, int b)
{//计算表达式值:主如果将大的表达式转化成小的表达式进行慢慢求值
    int c;
    if (theta == '+') c = a + b;
    else if (theta == '-') c = a - b;
    else if (theta == '*') c = a * b;
    else c = a / b;
    return c;
}//Operate
int IsOptr(char ch)
{
    char ptr[10] = { '+','-','*','/','(',')','#' };
    for (int i = 0; i < 7; i++)
    {
        if (ch == ptr[i])
            return true;
    }
    return false;
}
long result(char* a, SqStack1* OPND, SqStack2* OPTR)
{//求值
    char theta;
    int b, d, k = 0, i = 0, j = 0, num2 = 0;
    IntInitStack(OPND);
    CharInitStack(OPTR);
    CharPush(OPTR, '#');
    while (a[i] != '=')
    {
        if (!IsOptr(a[i]))
        {
            k++;
            if (k <= j)
            {
                num2 = (int(a[i]) - 48);
                i++;
            }
            if (k > j)
            {
                num2 = num2 * 10 + (int(a[i]) - 48);
                k = j = 0;
                i++;
            }
            if(!IsOptr(a[i]))
                k++;
            if (k == j)
                IntPush(OPND, num2);
        }
        else if (IsOptr(a[i]))
        {
            switch (Precede(a[i], CharGetTop(OPTR)))
            {
            case '<':CharPush(OPTR, a[i++]);
                if (a[i] != '(' && a[i] != ')')
                    j++;
                break;
            case '=':CharPop(OPTR); i++; break;
            case '>':theta = CharPop(OPTR);
                d = IntPop(OPND);
                b = IntPop(OPND);
                IntPush(OPND, Operate(b, theta, d));
                break;
            }//switch
        }//else if
    }//while
    printf("表达式的准确结果为:");
        printf("%d\n", IntGetTop(OPND));
    return(IntGetTop(OPND));
}//result
void Built_shitiKu()
{
    int i, num;
    xuanti* pstu;
    printf("输入试题数目: \n");
    scanf_s("%d", &num);
    fflush(stdin);
    pstu = (xuanti*)malloc(num * sizeof(xuanti));//动态分配内存
    if (pstu == NULL)
    {
        printf("没有足够的内存空间! \n");
    }
    else
    {
        for (i = 0; i < num; i++)
        {//输入试题
            printf("第%d道试题:", i + 1);
            gets_s(pstu[i].a);
            fflush(stdin);//清空键盘缓冲区
            printf("\n");
        }
        WriteToFile(pstu, num);//将pstu所指向的信息写入文件中
        memset(pstu, 0, num * sizeof(xuanti));//将pstu所指向的内存块清0
        ReadFromFile(pstu, num);//从文件中读取信息到pstu所指向的内存块中
        printf("试题列表;\n");
        for (i = 0; i < num; i++)
        {//输入试题
            printf("第%d道试题:", i + 1);
            printf("%s", pstu[i].a);
            printf("\n");
        }
        free(pstu);//释放动态分配的内存
    }
}
void WriteTopFile(xuanti* pstu, int num)
{
    FILE* fp;
fp = fopen("shitiku.txt", "at");
if (fp == NULL)
{
    printf("不克不及创建shitiku.txt\n");
    free(pstu);
    exit(0);
}
fwrite(pstu, sizeof(xuanti), num, fp);
fclose(fp);
}
void WriteToFile(xuanti* pstu, int num)
{
}
void ReadFromFile(xuanti* pstu, int num)
{//从试题库中提取试题
    FILE* fp;
    fp = fopen("shitiku.txt", "rt");
    if (fp == NULL)
    {
        printf("不可不及打开shitiku.txt\n");
        free(pstu);
        exit(0);
    }
    fread(pstu, sizeof(xuanti), num, fp);
    fclose(fp);
}
//***************************************************
void RecMark(int* m, int num)
{
    FILE* mp;
mp = fopen("markrec.txt", "at");
if (mp == NULL)
{
    printf("不可不及创建markrec.txt\n");
    free(m);
    exit(0);
}
fwrite(m, sizeof(int), num, mp);
fclose(mp);
}//Recmark
void LookMark(int* m, int num)
{//检查得分记录
    FILE* mp;
    mp = fopen("markrec.txt", "rt");
    if (mp == NULL)
    {
        printf("不克不及打开markrec.txt\n");
        free(m);
        exit(0);
    }
    fread(m, sizeof(int), num, mp);
    fclose(mp);
}
//**********************************************
void RecN(int* m, int num)
{
    FILE* mp;
mp = fopen("n_rec.txt", "wt");
if (mp == NULL)
{
    printf("不克不及创建n_rec.txt\n");
    free(m);
    exit(0);
}
fwrite(m, sizeof(int), num, mp);
fclose(mp);
}//Recmark
void LookN(int* m, int num)
{//检查m的值
    FILE* mp;
    mp = fopen("n_rec.txt", "rt");
    if (mp == NULL)
    {
        printf("不克不及打开n_rec.txt\n");
        free(m);
        exit(0);
    }
    fread(m, sizeof(int), num, mp);
    fclose(mp);
}
//****************************************
int excersice_begin()
{
    int i, j, temp, KEY[20]{};
    int mark, count = 0;
    int* Mark;
    char g;
    SqStack1 s1{}, * OPND;
    SqStack2 s2{}, * OPTR;
    xuanti* XT;
    OPND = &s1;
    OPTR = &s2;
    Mark = (int*)malloc(20 * sizeof(int));
    if (Mark == NULL)
    {
        printf("内存分配失败!\n");
    }
    else
    {
        XT = (xuanti*)malloc(20 * sizeof(xuanti));
        if (XT == NULL)
        {
            printf("内存分配失败!\n");
        }
        else {
            ReadFromFile(XT, 20);
            do
            {
                mark = 0;
                srand((unsigned)time(NULL));
                KEY[0] = rand() % 20;
                for (i = 1; i < 20; i++)
                {
                    while (1)
                    {
                        temp = rand() % 20;
                        for (j = 0; j < i; j++)
                        {
                            if (KEY[j] == temp)
                                break;
                        }
                        if (j == i)
                        {
                            KEY[i] = temp;
                            break;
                        }
                    }
                }
                system("cls");
                printf("随机的10个练习题:\n");
                for (i = 0; i <= 10; i++)
                {
                    printf("第%d个练习题:", i + 1);
                    printf("%s\n", XT[KEY[i]].a);
                    printf("请输入计算结果:");
                    scanf_s("%ld", &XT[KEY[i]].result);
                    fflush(stdin);
                    if (XT[KEY[i]].result == result(XT[KEY[i]].a, OPND, OPTR))
                    {
                        mark += 10;
                        printf("答案准确!");
                        printf("\n\n");
                    }
                    else
                    {
                        printf("答案错误!");
                        printf("\n\n");
                    }
                }
                printf("****得分情况****\n");
                printf("最初的得分为:%d\n", mark);
                if (mark >= 90)
                    printf("Very Good!\n");
                else if (mark >= 60)
                    printf("成绩不错.\n");
                else printf("很遗憾成绩不及格!\n");
                printf("\n");
                RecMark(Mark, count);
                Mark[count] = mark;
                count++;//记录次数递增
                printf("是否继续做练习?('y'--是,'n'--否):");
                g = getchar();
                fflush(stdin);
                printf("\n");
                if (count >= 20)//超出最大记录次数清0
                    count = 0;
            } 
            while (g == 'y');
            RecMark(Mark, count);
            return count;
            return_confirm();
        }
    }
    return false;
}
void Look_Mark(int count)
{//
    printf("是否检查历史得分?('y'--是,'n'--否):");
    int* Mark;
    int i;
    Mark = (int*)malloc(20 * sizeof(int));
    if (Mark == NULL)
    {
        printf("内存分配失败!\n");
    }
    else
    {
        system("cls");
        printf("****查询历史得分情况****\n");
        LookMark(Mark, count);
        for (i = 0; i <= count; i++)
            printf("****第%d次得%d分****\n", i + 1, Mark[i]);
        if (i > 1)
        {
            if (Mark[i - 1] > 60 || Mark[i - 2] > 60)
            {
                if (Mark[i - 1] > Mark[i - 2])
                    printf("有进步,还要加油哦.\n");
                else if (Mark[i - 1] == Mark[i - 2]) printf("成绩还可以,但没有进步,还要多多努力呀!\n");
                else printf("成绩有点降低,要多多练习,不要气馁!!\n");
            }
            else printf("成绩很欠好!要更加努力哦!\n");
        }
        else
        {
            if (Mark[0] >= 90)
                printf("Very Good!\n");
            else if (Mark[0] >= 60)
                printf("成绩不错.\n");
            else printf("很遗憾成绩不及格!\n");
        }
        return_confirm();
    }
}
void main()
{
    int m = 0;
    int* RN;
    char ch;
    RN = (int*)malloc(1 * sizeof(int));
    if (RN == NULL)
    {
        printf("内存分配失败!\n");
    }
    else
    {
        RN[0] = 0;
        printf("***如果是第一次运转***\n");
        printf("**请先建立n_rec.txt**\n");
        printf("*****否则会出错!*****\n");
        printf("('y'--创建**'n'--不建)\n");
        ch = getchar();
        if (ch == 'y')
            RecN(RN, 1);
        LookN(RN, 1);
        RN[0] += m;
        fflush(stdin);
        printf("是否向试题库中添加试题:");
        printf("('y'--是,'n'--否)?\n");
        ch = getchar();
        if (ch == 'y')
            Built_shitiKu();
    menu:page_title("操纵选单");
        printf("请用数字键选择操纵\n\n");
        printf("1 开始练习\n");
        printf("2 检查得分记录\n");
        printf("0 退出\n");
        printf("*********************\n");
        RN[0] += m;
        m = 0;
        switch (_getch())
        {
        case '1':m = excersice_begin();
            break;
        case '2':Look_Mark(RN[0]);
            break;
        case '0': {
            RecN(RN, 1);
            exit(0);
        }
        }
        system("cls");
        goto menu;
    }
}

编码的问题: https://blog.csdn.net/weixin_39684284/article/details/79025291?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2~default~CTRLIST~Rate-1.pc_relevant_paycolumn_v3&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2~default~CTRLIST~Rate-1.pc_relevant_paycolumn_v3&utm_relevant_index=2

利用栈求表达式的值
如有帮助,望采纳

#include<stdio.h>
#include<cstdio>
#include<math.h>
#include<stdlib.h>
#include<stack>
using namespace std;
stack<double>opnd;  //存储运算数 
stack<char>optr;  //存储运算符 
char pre; //记录当前字符的前一个字符,用于负数的判断 
int flag ; //值=1表示为负数,否则为正数 
 
void init(){  //初始化 
    optr.push('#');
    pre = '#';
    flag = 0;
}
 
int IsNumber(char c){  //检查是否是数字 
    if(c >= '0' && c <= '9')return 1;
    return 0;
}
 
 
int ErrorCheck(char c){  //返回1表示不是规定运算符 
   if(c == '+' || c == '-' || c == '*' || c == '/' || c == '(' || c == ')' || c == '#')return 0;
   return 1;
}
 
 
char Precede(char f,char l){   //运算级判断 
    if(f == '+' || f == '-'){
        if(l == '*' || l == '/' || l == '(') return '<';
        else return '>';
    }
    if(f == '*' || f == '/'){
        if(l == '(') return '<';
        else return '>';
    }
    if(f == '('){
        if(l == ')') return '=';
        else if(l!='#')return '<';
    } 
    if(f ==')' && l !='(') return '>';
    if(f == '#'){
        if(l == '#') return '=';
        else if(l!=')')return '<';
    } 
    
    return '0';
}
 
double Compute(double b,char oper,double a){
    if(oper == '-') return a-b;
    if(oper == '+') return a+b;
    if(oper == '*') return a*b;
    if(oper == '/') return a/b;
}
 
int main(){
    init();
    char ch = getchar();
    while(ch != '#' || optr.top() != '#'){
        if(IsNumber(ch)){
            double tot = 0;
            do{
            tot *= 10;
            tot += (ch - '0');
            pre = ch;
            ch = getchar();
            }while(IsNumber(ch));
            
            if(ch == '.'){  //小数点后的数值 
                ch = getchar();
                double tmp = 0.1;
                while(IsNumber(ch)){
                    tot += (ch - '0')*tmp;
                    tmp *= 0.1;
                    pre = ch;
                    ch = getchar();
                }
            }
            if(flag){
                tot = 0 - tot;
                flag = 0;
            }
            opnd.push(tot);
        }else if(ch == '-' && (pre == '#' || pre == '(')){   //负数的判定
            flag = 1;
            ch = getchar();
        }else {
          if(ErrorCheck(ch)) {
              printf("存在非规定的运算字符!\n"); 
              return 0;
          }
          
          
          switch(Precede(optr.top(),ch)){
               case '<' :{     //栈顶运算符优先级小 
                   optr.push(ch);
                   pre = ch;
                   ch = getchar();  //重新接收下一个字符 
                break;
               }
             case '=' :{
                 optr.pop(); //出栈一对括号
                 pre = ch;
                ch = getchar(); //重新接收下一个字符 
                break;
               }
             case '>' :{
                 char oper = optr.top(); 
                optr.pop();  //出栈一个运算符 
                 double a = opnd.top(); opnd.pop();
                double b = opnd.top(); opnd.pop();  //出栈两个操作数 
                
                double tot = Compute(a,oper,b);  //计算值,并将结果压入堆栈
                opnd.push(tot); 
                break;
             } 
             case '0':{
               printf("表达式语法错误,括号不匹配!\n");
               return 0;                 
                break;
             }
          } //switch
        }  //else
    } //while
    
    printf("%.2lf\n",opnd.top());
    opnd.pop();
    return 0;
}