如果觉得对你有帮助,能否点个赞或关个注,以示鼓励笔者呢?!博客目录 | 先点这里
偶然翻到了自己大一时候写的一些代码,代码冗余,但还是想保存下来,以作纪念。
1.运行效果
2.运行环境
源码(Dev5.4.0版本下可直接(.cpp文件)运行 gcc 4.7.2)
注意:由于部分代码为C11标准,后缀名应改为cpp运行
编译器下载链接:https://pan.baidu.com/s/1Hywq6hxzxMzX1-22ig2HdA
提取码:kd65
下载后解压即可使用
3.完整代码
#include<bits/stdc++.h>
#include<conio.h>
#include<windows.h>
using namespace std;
typedef long long ll;
/************全局变量*****************/
typedef struct
{
int x,y;
}pos;
string op="0123456789+-*/C()E";
int key[10][10]={
{
0,0,0,0,0},
{
0,14,13,12,11},
{
0,7,8,9,10},
{
0,4,5,6,10},
{
0,1,2,3,17},
{
0,0,15,16,17}
};
char mp[500][1000] = {
{
" C语言计算器1.0"},
{
""},
{
" 作者:山河"},
{
""},
{
" 说明"},
{
"┌───────────────────────────────────┐ "},
{
"│┌─────────────────────────────────┐│ WASD或者↑↓←→可操作虚拟光标的移动"},
{
"││ ││ "},
{
"│└─────────────────────────────────┘│ 当光标在虚拟键盘上时,按下空格可以将虚拟键盘上的数字输入 "},
{
"├────────┬────────┬────────┬────────┤ "},
{
"│ │ │ │ │ 让光标移动在Enter上面按下空格可计算结果 "},
{
"│ C │ / │ * │ - │ "},
{
"│ │ │ │ │ 支持括号等混合运算(除法自动向下取整,懒得施工了)"},
{
"├────────┼────────┼────────┼────────┤"},
{
"│ │ │ │ │ 小彩蛋:按F可进入输入模式(不建议使用,未施工完毕)"},
{
"│ 7 │ 8 │ 9 │ │"},
{
"│ │ │ │ │ 健壮性未完善(懒得修复),刷算法的一个小玩意(懒)"},
{
"├────────┼────────┼────────┤ + │"},
{
"│ │ │ │ │ 其它小游戏用H5写去咯,随缘更新,对C的一点爱好吧,毕竟不能总是黑框框"},
{
"│ 4 │ 5 │ 6 │ │"},
{
"│ │ │ │ │ "},
{
"├────────┼────────┼────────┼────────┤"},
{
"│ │ │ │ │ "},
{
"│ 1 │ 2 │ 3 │ E │"},
{
"│ │ │ │ n │ "},
{
"├────────┼────────┼────────│ t │"},
{
"│ │ │ │ e │ "},
{
"│ 0 │ ( │ ) │ r │"},
{
"│ │ │ │ │ "},
{
"└────────┴────────┴────────┴────────┘"}
};
/************函数声明*****************/
void gotoxy(int x, int y);//坐标函数
void HideCursor();//隐藏光标
void ShowCursor();//显示光标
void move();//控制虚拟键盘的指针移动函数
void load();//加载画面
void init();//初始化设置颜色和窗口大小
int pr(char o);//传入操作符,返回优先级
int find(char o);//判断是否为符号
string exp_deal(string in);//对表达式进行处理,避免多个数字相连
string exp_to_postexp(string in);//中缀表达式转为后缀表达式
ll calc(ll x,ll y,char o);//x为栈顶数,y为次顶数 y在算式前,x在后
string postexp_val(string in);//后缀表达式求值
string calc_res(string in);//传入输入的中缀表达式,计算结果
void gotoxy(int x, int y) //坐标函数
{
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
COORD pos;
pos.X = x;
pos.Y = y;
SetConsoleCursorPosition(handle, pos);
}
void HideCursor()//隐藏光标
{
CONSOLE_CURSOR_INFO cursor_info={
1,0};
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cursor_info);
}
void ShowCursor()//显示光标
{
CONSOLE_CURSOR_INFO cursor_info={
1,1};
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cursor_info);
}
//控制虚拟键盘的指针移动函数
void move()
{
int flag=0;
string in="";//输入的字符串
char ch1,ch2;
pos now_key,now_mp,last_key,last_mp;//key用来获取符号值,mp用来获取图上的位置
now_key.x=1,now_key.y=1;
now_mp.x=20,now_mp.y=17;
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),57);
gotoxy(now_mp.x,now_mp.y);
cout<<"C";
//同时启用wasd和方向键
while(1){
ch1=getch();
if(ch1==-32)//方向键为双键值
{
flag=0;
ch2=getch();
switch(ch2)
{
case 72:ch1='w';break;//上
case 80:ch1='s';break;//下
case 75:ch1='a';break;//左
case 77:ch1='d';break;//右
default: break;
}
}
switch(ch1)
{
case 'w':
case 'W':
if(now_key.x>1){
last_key.x=now_key.x,last_key.y=now_key.y;
last_mp.x=now_mp.x,last_mp.y=now_mp.y;
if(now_key.x==5&&now_key.y==4)break;
if(key[now_key.x][now_key.y]==10){
now_key.x-=2,now_mp.y-=6;break;}
if(key[now_key.x][now_key.y]==17){
now_key.x--,now_mp.y-=6;break;}
now_key.x--;
now_mp.y-=4;
}
break;
case 's':
case 'S':
if(now_key.x<5){
if(now_key.x==4&&now_key.y==4)break;
last_key.x=now_key.x,last_key.y=now_key.y;
last_mp.x=now_mp.x,last_mp.y=now_mp.y;
if(key[now_key.x][now_key.y]==11){
now_key.x+=2,now_mp.y+=6;break;}
if(key[now_key.x][now_key.y]==10){
now_key.x++,now_mp.y+=6;break;}
now_key.x++;
now_mp.y+=4;
}
break;
case 'a':
case 'A':
if(now_key.y>1){
last_key.x=now_key.x,last_key.y=now_key.y;
last_mp.x=now_mp.x,last_mp.y=now_mp.y;
now_key.y--;
if(key[now_key.x][now_key.y]==9){
now_mp.x-=9,now_mp.y-=2;break;}
if(key[now_key.x][now_key.y]==6){
now_mp.x-=9,now_mp.y+=2;break;}
now_mp.x-=9;
}
break;
case 'd':
case 'D':
if(now_key.y<4){
last_key.x=now_key.x,last_key.y=now_key.y;
last_mp.x=now_mp.x,last_mp.y=now_mp.y;
if(key[now_key.x][now_key.y]==9){
now_key.y++,now_key.x++,now_mp.x+=9,now_mp.y+=2;break;}
if(key[now_key.x][now_key.y]==6){
now_key.y++,now_mp.x+=9,now_mp.y-=2;break;}
if(key[now_key.x][now_key.y]==16){
now_key.y++,now_key.x--,now_mp.x+=9,now_mp.y-=4;break;}
now_key.y++;
now_mp.x+=9;
}
break;
case 'F'://启动键盘输入模式,提示光标闪烁
case 'f':
flag=1;
system("color 70");//设置颜色
gotoxy(50,13);
ShowCursor();//显示光标
char c;
while(1){
while((c=getch())!='k')
{
in+=c;
gotoxy(50-32,13);
for(int i=0;i<32;i++)cout<<" ";
gotoxy(50-in.length(),13);
cout<<in;
}
HideCursor();
gotoxy(50-32,13);
for(int i=0;i<32;i++)cout<<" ";
in=calc_res(in);
gotoxy(50-in.length(),13);
cout<<in;
in="";//清空
}
break;
case ' '://选中小键盘时
system("color 70");//设置颜色
flag=1;
int val=key[now_key.x][now_key.y];
if(val==14){
gotoxy(50-32,13);
for(int i=0;i<32;i++)cout<<" ";
in="";//清空
}
else if(val==17){
//提交
int len=in.length();
in=calc_res(in);
gotoxy(50-len,13);
for(int i=0;i<len;i++)cout<<" ";
gotoxy(50-in.length(),13);
cout<<in;
in="";
break;
}
else in+=op[val];//填入中缀表达式
gotoxy(50-in.length(),13);
cout<<in;
break;
}
if(!flag){
//先绘制移动前的符号
system("color 70");//设置颜色
gotoxy(last_mp.x,last_mp.y);
cout<<op[key[last_key.x][last_key.y]];
//绘制当前移动到的符号
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),57);
if(key[now_key.x][now_key.y]==17){
string s="Enter";
for(int i=0;i<5;i++)
{
gotoxy(now_mp.x,now_mp.y+i);
cout<<s[i];
}
}
else{
gotoxy(now_mp.x, now_mp.y);
cout<<op[key[now_key.x][now_key.y]];
}
}
}
}
void load()
{
for (int i = 0; i <= 30; i++)
{
gotoxy(15,6+i);
cout<<mp[i]<<endl;
}
}
void init()
{
system(" mode con cols=150 lines=40");//设置宽高
system("color 70");//设置颜色
HideCursor();
load();
move();
}
int pr(char o)//传入操作符,返回优先级
{
int pri[6]={
0,1,1,2,2,0};//左括号加减乘除 优先级
char op[6]={
'(','+','-','*','/','#'};//#做栈底使用
for(int i=0;i<6;i++)
if(op[i]==o)return pri[i];
}
int find(char o)
{
char op[10]={
'#','(','+','-','*','/','^',')'};
for(int i=0;i<10;i++)
if(op[i]==o)return 1;
return 0;
}
string exp_deal(string in)//对表达式进行处理,避免多个数字相连
{
string t="";
for(int i=0;i<in.length();i++)
{
t+=in[i];
if(in[i]>='0'&&in[i]<='9'&&find(in[i+1]))t+='@';
}
return t;
}
string exp_to_postexp(string in)//中缀转后缀
{
int pri[6]={
0,1,1,2,2,0};//左括号加减乘除 优先级
char op[6]={
'(','+','-','*','/','#'};//#做栈底使用
stack<char>s;
string res="";
s.push('#');
for(int i=0;i<in.length();i++)
{
if((in[i]>='0'&&in[i]<='9'||in[i]=='@')){
res+=in[i];
}
else {
//处理符号
if(in[i]=='(')s.push(in[i]);
else{
if(in[i]==')'){
while(s.top()!='('){
res+=s.top();s.pop();
}
s.pop();//弹出左括号
continue;
}
//当前扫描到的符号
if(pr(in[i])>pr(s.top()))s.push(in[i]);//优先级大于栈顶
else if(pr(in[i])<=pr(s.top())){
//优先级小于等于栈顶
while(pr(in[i])<=pr(s.top())){
res+=s.top();s.pop();}
s.push(in[i]);
}
}
}
}
while(s.top()!='#'){
res+=s.top();s.pop();
}
return res;
}
ll calc(ll x,ll y,char o)//x为栈顶数,y为次顶数 y在算式前,x在后
{
switch(o){
case '+':return x+y;
case '-':return y-x;
case '*':return x*y;
case '/':return y/x;
case '^':return pow(y,x);//虽然我忘记搞这个的界面了,以后再加?
}
}
string postexp_val(string in)//后缀表达式求值,维护一个栈即可
{
stack<ll>s;
ll m,n,now=0;
for(int i=0;i<in.length();i++){
if(in[i]>='0'&&in[i]<='9'){
//读入数字
now*=10;now+=in[i]-'0';
}
else if(in[i]=='@')s.push(now),now=0;
if(find(in[i])){
m=s.top();s.pop();
n=s.top();s.pop();
s.push(calc(m,n,in[i]));
}
}
ll num=s.top();
stringstream ss;
ss<<num;
return ss.str();
}
string calc_res(string in)//传入输入的中缀表达式,计算结果
{
in=exp_deal(in);//把中缀表达式进行处理
in=exp_to_postexp(in);//转为后缀表达式
return postexp_val(in);//后缀表达式求值
}
int main()
{
init();
return 0;
}