现在的位置: 首页 > 综合 > 正文

windows下表达式计算器C实现

2014年09月15日 ⁄ 综合 ⁄ 共 6698字 ⁄ 字号 评论关闭

算是学习windows编程后的第一个作品吧,想想还是把写过的东西留些在网上吧,算是另一种硬盘,电脑硬盘不靠谱(虽然从装机2年操作系统都没重装过一次...)

 

 

基本界面实现

#include <windows.h>
#include "core.h"   //计算器功能核心,表达树实现表达式计算,支持浮点数
#include "resource.h"

BOOL CALLBACK DialogProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
BOOL CALLBACK AboutDlgProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
char source [MAX_SIZE];
char dest [40];
double cal_result;
HINSTANCE hInst;

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
{
	hInst = hInstance;
	DialogBoxParam (hInstance, MAKEINTRESOURCE(IDD_DIALOG), NULL, DialogProc, 0);
	return 1;
}

BOOL CALLBACK DialogProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
	HWND hInput  = GetDlgItem (hDlg, IDC_INPUT);
	HWND hOut	 = GetDlgItem (hDlg, IDC_OUT);
	static HBITMAP	hBitmap;
	BITMAP	bitmap;
    HDC         hdc, hdcMem ;
    PAINTSTRUCT ps ;

	switch (message)
	{
		case WM_INITDIALOG:printf("a");
			SetWindowTextA (GetDlgItem (hDlg, IDC_INPUT), "0");
					
			hBitmap	= LoadBitmap(hInst, L"BitBlt");
			//GetObject (hBitmap, sizeof (bitmap), &bitmap);
			return true;

		case WM_PAINT:
		 
		 hdc = BeginPaint(hDlg, &ps);
		 hdcMem = CreateCompatibleDC(hdc);
		 SelectObject(hdcMem, hBitmap);

         StretchBlt (hdc, 0, 0, 550, 420,
                      hdcMem, 0, 0, 550, 380, MERGECOPY) ;

		 DeleteDC(hdcMem);
		 EndPaint (hDlg, &ps);
		 return true;

		case WM_COMMAND:
			switch (LOWORD (wParam))
			{
				case IDM_HELP_ABOUT:
					if (DialogBox (hInst, TEXT ("AboutBox"), hDlg, AboutDlgProc))
						InvalidateRect (hDlg, NULL, TRUE) ;
					return 0 ;

				case IDC_0:
					strcat (source, "0");
					SetWindowTextA (hInput, source); 
					break;

				case IDC_1:
					strcat (source, "1");
					SetWindowTextA (hInput, source); 
					break;

				case IDC_2:
					strcat (source, "2");
					SetWindowTextA (hInput, source); 
					break;

				case IDC_3:
					strcat (source, "3");
					SetWindowTextA (hInput, source); 
					break;

				case IDC_4:
					strcat (source, "4");
					SetWindowTextA (hInput, source); 
					break;

				case IDC_5:
					strcat (source, "5");
					SetWindowTextA (hInput, source); 
					break;

				case IDC_6:
					strcat (source, "6");
					SetWindowTextA (hInput, source); 
					break;

				case IDC_7:
					strcat (source, "7");
					SetWindowTextA (hInput, source); 
					break;

				case IDC_8:
					strcat (source, "8");
					SetWindowTextA (hInput, source); 
					break;

				case IDC_9:
					strcat (source, "9");
					SetWindowTextA (hInput, source); 
					break;

				case IDC_ADD:
					strcat (source, "+");
					SetWindowTextA (hInput, source); 
					break;

				case IDC_SUB:
					strcat (source, "-");
					SetWindowTextA (hInput, source); 
					break;

				case IDC_MUL:
					strcat (source, "*");
					SetWindowTextA (hInput, source); 
					break;

				case IDC_DIV:
					strcat (source, "/");
					SetWindowTextA (hInput, source); 
					break;

				case IDC_DOT:
					strcat (source, ".");
					SetWindowTextA (hInput, source); 
					break;

				case IDC_DEL:
					source [strlen(source)-1] = '\0';
					SetWindowTextA (hInput, source); 
					break;

				case IDC_CLEAR:
					strcpy (source, "\0");
					SetWindowTextA (hInput, "0");
					SetWindowTextA (hOut, "0");
					break;

				case IDC_LEFT_BRACKET:
					strcat (source, "(");
					SetWindowTextA (hInput, source); 
					break;

				case IDC_RIGHT_BRACKET:
					strcat (source, ")");
					SetWindowTextA (hInput, source); 
					break;

				case IDC_VALUE:
					if (head != NULL)
					{
						destroy(head);//销毁表达式树
						head = NULL;
					}
					if (!check1(source))
					{
						MessageBox (hDlg, TEXT("括号不匹配"), TEXT("提示"), 0);
						break;
					}
					if (!check2(source))
					{
						MessageBox (hDlg, TEXT("表达式错误"), TEXT("提示"), 0);
						break;
					}
					convert(source);
					postfix(source);
					head = Create_Tree (&head, source);
					cal_result = cal(head);
					sprintf (dest,"%.4lf",cal_result);
					SetWindowTextA (hOut, dest); 
					break;

				case IDCANCEL:
					if (head != NULL)
					{
						destroy(head);
						head = NULL;
					}

					EndDialog(hDlg,0);
					return true;
			}
			return true;
	}
	return false;
}

BOOL CALLBACK AboutDlgProc (HWND hDlg, UINT message, 
                            WPARAM wParam, LPARAM lParam)
{
     switch (message)
     {
     case WM_INITDIALOG :
          return TRUE ;
          
     case WM_COMMAND :
          switch (LOWORD (wParam))
          {
		  case IDOK :
          case IDCANCEL :
               EndDialog (hDlg, 0) ;
               return TRUE ;
          }
          break ;
     }
     return FALSE ;
}

 

#ifndef CORE_H
#define CORE_H
#include <stdio.h>
#include <string.h>
#include <ctype.h>

#define MAX_SIZE 40
#define MAX_STACK 15
#define MALLOC(p,s)\
	if(!((p) = (ExpTree *) malloc (s) ) )\
	{\
		fprintf(stderr,"insufficient memory\n");\
		exit(EXIT_FAILURE);\
	}

typedef enum { Oper, Date, End } flag; 

typedef struct v
{
	flag tag;
	double value;
}element;//表达式树节点结构
element ele[MAX_SIZE];//存储转换表达式树所需数组

typedef struct NODE
{
	element date;
	struct NODE* left;
	struct NODE* right;
}ExpTree;
ExpTree *head;



int postfix(char *str)//转换成后缀表达式
{
	element temp[MAX_SIZE];
	//char s[MAX_SIZE];//源字符串副本
	char stack[MAX_SIZE];//符号栈
	int i,top=-1,j=0;
	memset(stack,0,sizeof(stack));
	//strcpy(s,str);
	memcpy(temp,ele,sizeof(ele));
	memset(ele,0,sizeof(ele));
	//memset(str,0,sizeof(str));
	for(i = 0; temp[i].tag != End ; i++)
	{
		switch(temp[i].tag)
		{
		case Oper:
			switch ((int)temp[i].value )
			{
				case '*':
					while(top>=0&&stack[top]!='('&&stack[top]!='+'&&stack[top]!='-'&&top!=-1)
					{
						ele[j].value=stack[top--];
						ele[j++].tag=Oper;
					}
					stack[++top]='*';
				break;
				case '/':
					while(top>=0&&stack[top]!='('&&stack[top]!='+'&&stack[top]!='-'&&top!=-1)
					{
						ele[j].value=stack[top--];
						ele[j++].tag=Oper;
					}
					stack[++top]='/';
					break;
				case '+':
					while(top>=0&&stack[top]!='(')
					{
						ele[j].value=stack[top--];
						ele[j++].tag=Oper;
					}
					stack[++top]='+';
					break;
				case '-':
					while(top>=0&&stack[top]!='(')
					{
						ele[j].value=stack[top--];
						ele[j++].tag=Oper;
					}
					stack[++top]='-';
					break;
				case '(':
					stack[++top]='(';
					break;
				case ')':
					while(stack[top]!='(')
					{
						ele[j].value=stack[top--];
						ele[j++].tag=Oper;
					}
					top--;
					break;
			}	
			break;
		case Date:
			ele[j].tag	= Date;
			ele[j++].value= temp[i].value;
			break;
		}
	}
	while(top>=0)
	{
		ele[j].tag	= Oper;
		ele[j++].value=stack[top--];
	}
	ele[j].tag = End;
	return TRUE;
}

void convert(char *str)//将表达式中的浮点字符串转换成浮点数
{
	char temp[MAX_SIZE/2];//临时存储浮点数的字符串用于转换成浮点数
	int i,j,t;
	for (i = 0, j=0; str[i] != '\0'; i++)
	{
		if (str[i] == '+' || str[i] == '*' || str[i] == '/' || str[i] == '(' || str[i] == ')' || (str[i] == '-' && i!=0 && str[i-1] != '(')  )//处理了负数的特殊情况
		{
			ele[j].tag		= Oper;
			ele[j].value	= str[i];
			j++;
		}
		else
		{
			t = 0;
			while (1)
			{
				temp[t++] = str[i];
				if (str[i+1] == '+' || str[i+1] == '-' || str[i+1] == '*' || str[i+1] == '/' || str[i+1] == '(' || str[i+1] == ')' || str[i+1] == '\0')
					break;
				i++;
			}
			temp[t]='\0';
			ele[j].tag	= Date;
			ele[j].value= atof(temp);
			strcpy(temp,"\0");
			j++;
		}
	}
	ele[j].tag	= End;
}

ExpTree* Create_Tree(ExpTree **root,char *str)//生成表达式树
{
	ExpTree *p=NULL;
	ExpTree *stack[MAX_STACK];
	int i,top=-1;
	for(i = 0; ele[i].tag != End; i++)
	{
		switch(ele[i].tag)
		{
			case Oper:
				MALLOC( p, sizeof(*p) );
				p->date  = ele[i];
				p->right = stack[top--];
				p->left  = stack[top--];
				*root    = stack[++top]=p;
				break;
			case Date:
				MALLOC( p, sizeof(*p) );
				p->date = ele[i];
				p->left = p->right=NULL;
				stack[++top] = p;
				break;
		}
	}
	return *root;
}

double cal (ExpTree *root)//计算表达式树
{
	double result1,result2;
	if ( root)
	{
		result1 = cal (root->left);
		result2 = cal (root->right);
		switch (root->date.tag)
		{
		case Oper:
			switch ( (int)root->date.value)
			{	
				case '+': return result1 + result2;
				case '-': return result1 - result2;
				case '*': return result1 * result2;
				case '/': return result1 / result2;
			}
		case Date: return root->date.value;
		}
	}
	return 0;
}

void destroy(ExpTree *root)
{
	if (root)
	{
		destroy (root->left);
		destroy (root->right);
		free (root);
	}
}


int check1(char *str)//检查括号匹配
{
	int brac=0,i;
	for(i=0;str[i]!='\0';i++)
	{
		if(str[i]=='(')
			brac++;
		if(str[i]==')')
			brac--;
		if(brac < 0)
			return FALSE;
	}
	if(brac==0)
		return TRUE;

	return FALSE;
}

int check2(char *str)//检查表达式
{
	int oper,i;
	if ( !isdigit(str[0]) && str[0] != '(' && str[0] != '-' )
		return FALSE;
	if (!isdigit(str[strlen(str)-1]) && str[strlen(str)-1] != ')' )
		return FALSE;
	for ( i = 0,oper = 0; str[i] != '\0'; i++)
		if ((str[i] == '+' || str[i] == '-' || str[i] == '*' || str[i] == '/') && (str[i+1] == '+' || str[i+1] == '-' || str[i+1] == '*' || str[i+1] == '/' ) ) //连续多个操作符
			return FALSE;
	return TRUE;
}

#endif

抱歉!评论已关闭.