Linux下实现的简单的计算器程序。
(1)caculator.c:
/*Linux下实现一个计算器程序, 它有如下的要求: *1. 能识别英文数字:比如 three hundred and ninety two, 要能转换为392. *2. 能识别英文的加减乘除: Add, minus, multiply, divide. *3. 能识别符号的加减乘除: +, -, *, / * *例子如下: *输入:three hundred and ninety two multiply 7 *结果:2744 * *输入:12 minus 3 *结果: 9 */ #include <stdio.h> #include <string.h> #include <stdlib.h> #include <setjmp.h> #define bool int #define true 1 #define false 0 void ltrim(char *str, const char ch); void rtrim(char *str, const char ch); int caculate(const char *input, int *result); char get_operant(char *data, int* op1, int* op2); int skip_work(char *data); jmp_buf jmp; int main() { int result; char input[1024] = {0}; puts("***********self made english caculator*****************"); puts("input exit to go out!"); while(1) { setjmp(jmp); puts("please input an expression:"); if(gets(input) == NULL) { puts("get input data failed!"); return -1; } ltrim(input, ' '); rtrim(input, ' '); if(strcmp(input, "exit") == 0) break; if(skip_work(input) < 0) puts("skip failed!"); if(caculate(input, &result) == 0) { printf("The result is:%s = %d\n", input, result); } else { printf("cannot caculate!\n"); } } puts("out of the caculator!"); return 0; } void ltrim(char *str, const char ch) { char *ptr; for (ptr = str; *ptr; ptr ++) { if(*ptr != ch) break; } strcpy(str, ptr); } void rtrim(char *str, const char ch) { int i; int len = strlen(str); for (i = len - 1; i >= 0; i--) { if(str[i] != ch) break; } str[i + 1] = '\0'; } int caculate(const char *str, int *result) { char *input = (char*)malloc(strlen(str) + 1); strcpy(input, str); int op1, op2; char op; float div; op = get_operant(input, &op1, &op2); free(input); input = NULL; switch(op) { case '+': *result = op1 + op2; break; case '-': *result = op1 - op2; break; case '*': *result = op1 * op2; break; case '/': if(op2 == 0) { puts("divisor illegal!"); return -1; } else div = (float)op1 / op2; printf("The result is:%s = %0.3f\n", str, div); longjmp(jmp, 1); break; default: return -1; } return 0; } char get_operant(char *data, int* op1, int* op2) { static const char *op_list[]={"+", "-", "*", "/"}; int i; char *temp = data; char *change; char *tok = NULL; char *steptok = NULL; while(*temp != '\0') { if(*temp == ' ') { change = temp; while(*change != '\0') { *change = *(change + 1); change ++; } } temp++; } char data_mp[100] = {0}; //char data_mp[100] = {0}; int sum = 0; strcpy(data_mp, data); char tok_one[50] = {0}; char tok_two[50] = {0}; char tok_one_temp[50] = {0}; char tok_two_temp[50] = {0}; for (i = 0; i < 4; i++) { tok = strtok(data, op_list[i]); if (strcmp(data, data_mp) != 0) break; } strcpy(tok_one, tok); strcpy(tok_one_temp, tok); tok = strtok(NULL, op_list[i]); strcpy(tok_two, tok); strcpy(tok_two_temp, tok); //printf("tok_one:%s\n", tok_one); steptok = strtok(tok_one, "and"); if(strcmp(tok_one_temp, steptok) != 0) { sum = atoi(steptok); steptok = strtok(NULL, "and"); sum += atoi(steptok); *op1 = sum; } else *op1 = atoi(tok_one); steptok = strtok(tok_two, "and"); if(strcmp(tok_two_temp, steptok) != 0) { sum = atoi(steptok); steptok = strtok(NULL, "and"); sum += atoi(steptok); *op2 = sum; } else *op2 = atoi(tok_two); //printf("%d,%d,%c\n",*op1,*op2,*op_list[i]); return *op_list[i]; } int skip_work(char *data) { static const char *symbol[8]={ "plus", "minus", "multiply", "divide", "+", "-", "*", "/"}; static const char *link[8]={ "hundred", "thousand", "million", "billion", "00", "000", "000000, 000000000"}; static const char *decade[16] ={ "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety", "20", "30", "40", "50", "60", "70", "80", "90"}; static const char *digit[20]={ "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen","fifteen", "sixteen", "seventeen", "eighteen", "nineteen"}; bool flag = false; char *toks = " "; char *tok = strtok(data, toks); int i, j, m ,n; char temp_tok[20] = {0}; char data_temp[50]= {0}; while(tok) { for(i = 0; i < 20; i++) if(!strcmp(tok, digit[i])) { if(flag == true) { i += atoi(decade[m + 8]); } sprintf(temp_tok, "%d", i); break; } for(j = 0; j < 4; j++) { if(!strcmp(tok, link[j])) { strcat(data_temp, link[j + 4]); //sprintf(temp_tok, i*atoi(j+4)); break; } } if(j != 4) { tok = strtok(NULL, toks); continue; } for(m = 0; m < 8; m++) { if(!strcmp(tok, decade[m])) { flag = true; //strcat(data_temp, decade[m + 8]); break; } } if (m != 8) { tok = strtok(NULL, toks); continue; } for(n = 0; n < 4;n++) if(!strcmp(tok, symbol[n])) { strcpy(temp_tok, symbol[n+4]); break; } if(i == 20 && j == 4 && m == 8 && n == 4) strcpy(temp_tok, tok); //if (!strcmp(temp_tok, data)) // strcpy(data, temp_tok); //else // printf("dddd11:%s\n", temp_tok); strcat(data_temp, temp_tok); tok = strtok(NULL, toks); flag = false; } strcpy(data, data_temp); return 0; }(2)编译运行
//Linux 下实现计算器程序 /* eng_cac.c */ /* english caculator */ #include <ctype.h> #include <stdio.h> #include <string.h> int skip_space(const char *p, int *io_index) { int index; if (p == NULL || io_index == NULL) { return -1; } index = *io_index; if (index < 0) { return -1; } if (!isspace(p[index])) { return -1; } do { ++index; }while (isspace(p[index])); *io_index = index; return 0; } int get_word(const char *p, int *io_index, int *o_start, int *o_len) { int index; if (p == NULL || io_index == NULL || o_start == NULL || o_len == NULL) { return -1; } index = *io_index; if (index < 0) { return -1; } if (isalpha(p[index])) { do { ++index; }while (isalpha(p[index])); *o_start = *io_index; *o_len = index - *io_index; *io_index = index; return 0; }else if (ispunct(p[index])) { ++index; *o_start = *io_index; *o_len = 1; *io_index = index; return 0; }else { return -1; } } int get_token(const char *tok, int len, const char *tok_tab[], int tab_len) { int i; if (tok == NULL || tok_tab == NULL) { return -1; } if (len <= 0 || tab_len <= 0) { return -1; } for (i = 0; i < tab_len; ++i) { if (strncmp(tok, tok_tab[i], len) == 0) { if (tok_tab[i][len] == '\0') { return i; } } } return -1; } int skip_word(const char *p, int *io_index, const char *s) { int index; int start, len; if (p == NULL || io_index == NULL || s == NULL) { return -1; } index = *io_index; if (index < 0) { return -1; } skip_space(p, &index); if (get_word(p, &index, &start, &len) == 0) { if (strncmp(p + start, s, len) == 0) { *io_index = index; return 0; } } return -1; } int get_english_number_bellow_twenty(const char *p, int *io_index, int *o_value) { static const char *digit20[20] = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen", }; int index; int start; int len; int tok; if (p == NULL || io_index == NULL || o_value == NULL) { return -1; } index = *io_index; if (index < 0) { return -1; } skip_space(p, &index); if (get_word(p, &index, &start, &len) == 0) { tok = get_token(p + start, len, digit20, 20); if (tok != -1) { *o_value = tok; *io_index = index; return 0; } } return -1; } int get_english_number_decade(const char *p, int *io_index, int *o_value) { static const char *decades[8] = { "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety", }; int index; int start, len; int value; int retn; if (p == NULL || io_index == NULL || o_value == NULL) { return -1; } index = *io_index; if (index < 0) { return -1; } skip_space(p, &index); if (get_word(p, &index, &start, &len) == 0) { retn = get_token(p + start, len, decades, 8); if (retn != -1) { value = retn * 10 + 20; *o_value = value; *io_index = index; return 0; } } return -1; } int get_english_number_bellow_hundred(const char *p, int *io_index, int *o_value) { int index; int value; int digit; int decade_yes; if (p == NULL || io_index == NULL || o_value == NULL) { return -1; } index = *io_index; if (index < 0) { return -1; } decade_yes = 0; if (get_english_number_decade(p, &index, &value) == -1) { value = 0; }else { decade_yes = 1; } if (get_english_number_bellow_twenty(p, &index, &digit) == 0) { if (decade_yes && digit == 0) { return -1; } value += digit; }else { if (!decade_yes) { return -1; } } *o_value = value; *io_index = index; return 0; } int get_english_number_base(const char *p, int *io_index, int *o_base) { static const char *more[] = { "thousand", "million", "billion", }; static const int base[] = { 1000, 1000000, 1000000000, }; int index; int start,len; int retn; if (p == NULL || io_index == NULL || o_base == NULL) { return -1; } index = *io_index; if (index < 0) { return -1; } skip_space(p, &index); if (get_word(p, &index, &start, &len) == 0) { retn = get_token(p + start, len, more, 4); if (retn != -1) { *o_base = base[retn]; *io_index = index; return 0; } } return -1; } int get_english_number_bellow_thousand(const char *p, int *io_index, int *o_value) { int index; int value; int sum; if (p == NULL || io_index == NULL || o_value == NULL) { return -1; } index = *io_index; if (index < 0) { return -1; } if (get_english_number_bellow_hundred(p, &index, &sum) == 0) { if (sum > 0 && sum < 10) { if (skip_word(p, &index, "hundred") == 0) { sum *= 100; if (skip_word(p, &index, "and") == 0) { if (get_english_number_bellow_hundred(p, &index, &value) == -1) { return -1; } if (value == 0) { return -1; } sum += value; } } } *o_value = sum; *io_index = index; return 0; }else if (skip_word(p, &index, "a") == 0) { sum = 1; if (skip_word(p, &index, "hundred") == 0) { sum *= 100; if (skip_word(p, &index, "and") == 0) { if (get_english_number_bellow_hundred(p, &index, &value) == -1) { return -1; } if (value == 0) { return -1; } sum += + value; } } *o_value = sum; *io_index = index; return 0; } return -1; } int get_english_number(const char *p, int *io_index, int *o_value) { int index; int value; int sum; int base; if (p == NULL || io_index == NULL || o_value == NULL) { return -1; } index = *io_index; if (index < 0) { return -1; } sum = 0; for (;;) { if (get_english_number_bellow_thousand(p, &index, &value) == 0) { if (value == 0) { break; } if (get_english_number_base(p, &index, &base) == 0) { value *= base; if (sum > 0 && value >= sum) { return -1; } sum += value; continue; } sum += value; } if (sum == 0) { return -1; } break; } *o_value = sum; *io_index = index; return 0; } int get_operator1(const char *p, int *io_index, int *o_op) { static const char *op_list[] = { "positive", "+", "negative", "-", }; int index; int start, len; int retn; if (p == NULL || io_index == NULL || o_op == NULL) { return -1; } index = *io_index; if (index < 0) { return -1; } skip_space(p, &index); if (get_word(p, &index, &start, &len) == 0) { retn = get_token(p + start, len, op_list, 8); if (retn != -1) { *o_op = retn / 2; *io_index = index; return 0; } } return -1; } int get_operator2(const char *p, int *io_index, int *o_op) { static const char *op_list[] = { "plus", "+", "minus", "-", "multiply", "*", "divide", "/", }; int index; int start, len; int retn; if (p == NULL || io_index == NULL || o_op == NULL) { return -1; } index = *io_index; if (index < 0) { return -1; } skip_space(p, &index); if (get_word(p, &index, &start, &len) == 0) { retn = get_token(p + start, len, op_list, 8); if (retn != -1) { if ((retn & 1) == 0) { skip_word(p, &index, "with"); } *o_op = retn / 2; *io_index = index; return 0; } } return -1; } int get_arab_number(const char *p, int *io_index, int *o_value) { int index; int value; if (p == NULL || io_index == NULL || o_value == NULL) { return -1; } index = *io_index; if (index < 0) { return -1; } skip_space(p, &index); if (isdigit(p[index])) { value = 0; do { value = value * 10 + p[index] - '0'; index++; }while (isdigit(p[index])); *o_value = value; *io_index = index; return 0; } return -1; } int get_number(const char *p, int *io_index, int *o_value) { int index; int value; if (p == NULL || io_index == NULL || o_value == NULL) { return -1; } index = *io_index; if (index < 0) { return -1; } if (get_english_number(p, &index, &value) == 0 || get_arab_number(p, &index, &value) == 0) { *o_value = value; *io_index = index; return 0; } return -1; } int get_oprand(const char *p, int *io_index, int *o_value) { int index; int op; int d1; int result; if (p == NULL || io_index == NULL || o_value == NULL) { return -1; } index = *io_index; if (index < 0) { return -1; } /* one oprand operation */ if (get_operator1(p, &index, &op) == 0) { if (get_number(p, &index, &d1) != 0) { return -1; } switch (op) { case 0: result = d1; break; case 1: result = -d1; break; default: return -1; } }else { if (get_number(p, &index, &result) != 0) { return -1; } } *o_value = result; *io_index = index; return 0; } int get_end(const char *p, int *io_index) { int index; if (p == NULL || io_index == NULL) { return -1; } index = *io_index; if (index < 0) { return -1; } skip_space(p, &index); if (p[index] == '\0') { *io_index = index; return 0; } return -1; } int caculate(const char *exp, int *o_value) { int op; /* operator */ int d1, d2; /* oprand number */ int result; /* store the expression result */ int index; if (exp == NULL || o_value == NULL) { return -1; } index = 0; if (get_oprand(exp, &index, &result) == -1) { return -1; } /* conjunction operation */ while (get_end(exp, &index) == -1) { /* two oprands operation */ d1 = result; if (get_operator2(exp, &index, &op) == -1) { return -1; } if (get_oprand(exp, &index, &d2) == -1) { return -1; } switch (op) { case 0: result = d1 + d2; break; case 1: result = d1 - d2; break; case 2: result = d1 * d2; break; case 3: if (d2 == 0) { return -1; } result = d1 / d2; break; default: return -1; } } *o_value = result; return 0; /* end of conjunction */ } int read_line(char *buff, int buf_len) { int len; if (buff == NULL || buf_len <= 0) { return -1; } for (;;) { if (fgets(buff, buf_len, stdin) == NULL) { return -1; } len = strlen(buff) - 1; if (buff[len] == '\n') { buff[len] = '\0'; return 0; } /* check for last not terminated line in file */ if (fgets(buff, buf_len, stdin) == NULL) { return 0; } /* line length is greater than buffer */ /* skip rest line content */ for (;;) { len = strlen(buff) - 1; if (buff[len] == '\n') { return -2; /* buffer overflow, skip the whole line */ } if (fgets(buff, buf_len, stdin) == NULL) { return -1; } } } } int main(void) { char cmd_line[1024]; int result; puts("English Caculator"); puts("Enter an expression"); puts("Ctrl-Z to exit\n"); for (;;) { printf(": "); switch (read_line(cmd_line, sizeof(cmd_line))) { case 0: break; default: case -1: puts(""); return 0; case -2: puts("Buffer Overflow"); continue; } if (caculate(cmd_line, &result) == 0) { printf("'%s' = %d\n", cmd_line, result); }else { printf("'%s' = E, Invalid Expression\n", cmd_line); } } }(2)编译运行