免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123
最近访问板块 发新帖
楼主: toddytao
打印 上一主题 下一主题

Linux 下实现计算器程序,高手请进!! [复制链接]

论坛徽章:
5
狮子座
日期:2013-08-20 10:12:24午马
日期:2013-11-23 18:04:102015年辞旧岁徽章
日期:2015-03-03 16:54:152015亚冠之德黑兰石油
日期:2015-06-29 18:11:1115-16赛季CBA联赛之新疆
日期:2024-02-21 10:00:53
21 [报告]
发表于 2011-08-10 10:47 |只看该作者
哥哥,你弄个github来传代码吧……

论坛徽章:
2
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:56:11
22 [报告]
发表于 2011-08-10 12:07 |只看该作者
修正英文数字正规表示法。

  1. /* eng_cac.c */

  2. /* english caculator */

  3. #include <ctype.h>
  4. #include <stdio.h>
  5. #include <string.h>

  6. int skip_space(const char *p, int *io_index)
  7. {
  8.         int index;

  9.         if (p == NULL || io_index == NULL) {
  10.                 return -1;
  11.         }
  12.         index = *io_index;
  13.         if (index < 0) {
  14.                 return -1;
  15.         }
  16.         if (!isspace(p[index])) {
  17.                 return -1;
  18.         }
  19.         do {
  20.                 ++index;
  21.         }while (isspace(p[index]));
  22.         *io_index = index;
  23.         return 0;
  24. }

  25. int get_word(const char *p, int *io_index, int *o_start, int *o_len)
  26. {
  27.         int index;

  28.         if (p == NULL || io_index == NULL || o_start == NULL || o_len == NULL) {
  29.                 return -1;
  30.         }
  31.         index = *io_index;
  32.         if (index < 0) {
  33.                 return -1;
  34.         }
  35.         if (isalpha(p[index])) {
  36.                 do {
  37.                         ++index;
  38.                 }while (isalpha(p[index]));
  39.                 *o_start = *io_index;
  40.                 *o_len = index - *io_index;
  41.                 *io_index = index;
  42.                 return 0;
  43.         }else if (ispunct(p[index])) {
  44.                 ++index;
  45.                 *o_start = *io_index;
  46.                 *o_len = 1;
  47.                 *io_index = index;
  48.                 return 0;
  49.         }else {
  50.                 return -1;
  51.         }
  52. }

  53. int get_token(const char *tok, int len, const char *tok_tab[], int tab_len)
  54. {
  55.         int i;

  56.         if (tok == NULL || tok_tab == NULL) {
  57.                 return -1;
  58.         }
  59.         if (len <= 0 || tab_len <= 0) {
  60.                 return -1;
  61.         }
  62.         for (i = 0; i < tab_len; ++i) {
  63.                 if (strncmp(tok, tok_tab[i], len) == 0) {
  64.                         if (tok_tab[i][len] == '\0') {
  65.                                 return i;
  66.                         }
  67.                 }
  68.         }
  69.         return -1;
  70. }

  71. int skip_word(const char *p, int *io_index, const char *s)
  72. {
  73.         int index;
  74.         int start, len;

  75.         if (p == NULL || io_index == NULL || s == NULL) {
  76.                 return -1;
  77.         }
  78.         index = *io_index;
  79.         if (index < 0) {
  80.                 return -1;
  81.         }
  82.         skip_space(p, &index);
  83.         if (get_word(p, &index, &start, &len) == 0) {
  84.                 if (strncmp(p + start, s, len) == 0) {
  85.                         *io_index = index;
  86.                         return 0;
  87.                 }
  88.         }
  89.         return -1;
  90. }

  91. int get_english_number_bellow_twenty(const char *p, int *io_index, int *o_value)
  92. {
  93.         static const char *digit20[20] = {
  94.                 "zero",
  95.                 "one",
  96.                 "two",
  97.                 "three",
  98.                 "four",
  99.                 "five",
  100.                 "six",
  101.                 "seven",
  102.                 "eight",
  103.                 "nine",
  104.                 "ten",
  105.                 "eleven",
  106.                 "twelve",
  107.                 "thirteen",
  108.                 "fourteen",
  109.                 "fifteen",
  110.                 "sixteen",
  111.                 "seventeen",
  112.                 "eighteen",
  113.                 "nineteen",
  114.         };
  115.         int index;
  116.         int start;
  117.         int len;
  118.         int tok;

  119.         if (p == NULL || io_index == NULL || o_value == NULL) {
  120.                 return -1;
  121.         }
  122.         index = *io_index;
  123.         if (index < 0) {
  124.                 return -1;
  125.         }
  126.         skip_space(p, &index);
  127.         if (get_word(p, &index, &start, &len) == 0) {
  128.                 tok = get_token(p + start, len, digit20, 20);
  129.                 if (tok != -1) {
  130.                         *o_value = tok;
  131.                         *io_index = index;
  132.                         return 0;
  133.                 }
  134.         }
  135.         return -1;
  136. }

  137. int get_english_number_decade(const char *p, int *io_index, int *o_value)
  138. {
  139.         static const char *decades[8] = {
  140.                 "twenty",
  141.                 "thirty",
  142.                 "forty",
  143.                 "fifty",
  144.                 "sixty",
  145.                 "seventy",
  146.                 "eighty",
  147.                 "ninety",
  148.         };
  149.         int index;
  150.         int start, len;
  151.         int value;
  152.         int retn;

  153.         if (p == NULL || io_index == NULL || o_value == NULL) {
  154.                 return -1;
  155.         }
  156.         index = *io_index;
  157.         if (index < 0) {
  158.                 return -1;
  159.         }
  160.         skip_space(p, &index);
  161.         if (get_word(p, &index, &start, &len) == 0) {
  162.                 retn = get_token(p + start, len, decades, 8);
  163.                 if (retn != -1) {
  164.                         value = retn * 10 + 20;
  165.                         *o_value = value;
  166.                         *io_index = index;
  167.                         return 0;
  168.                 }
  169.         }
  170.         return -1;
  171. }

  172. int get_english_number_bellow_hundred(const char *p, int *io_index, int *o_value)
  173. {
  174.         int index;
  175.         int value;
  176.         int digit;
  177.         int decade_yes;

  178.         if (p == NULL || io_index == NULL || o_value == NULL) {
  179.                 return -1;
  180.         }
  181.         index = *io_index;
  182.         if (index < 0) {
  183.                 return -1;
  184.         }
  185.         decade_yes = 0;
  186.         if (get_english_number_decade(p, &index, &value) == -1) {
  187.                 value = 0;
  188.         }else {
  189.                 decade_yes = 1;
  190.         }
  191.         if (get_english_number_bellow_twenty(p, &index, &digit) == 0) {
  192.                 if (decade_yes && digit == 0) {
  193.                         return -1;
  194.                 }
  195.                 value += digit;
  196.         }else {
  197.                 if (!decade_yes) {
  198.                         return -1;
  199.                 }
  200.         }
  201.         *o_value = value;
  202.         *io_index = index;
  203.         return 0;
  204. }

  205. int get_english_number_base(const char *p, int *io_index, int *o_base)
  206. {
  207.         static const char *more[] = {
  208.                 "thousand",
  209.                 "million",
  210.                 "billion",
  211.         };
  212.         static const int base[] = {
  213.                 1000,
  214.                 1000000,
  215.                 1000000000,
  216.         };
  217.         int index;
  218.         int start,len;
  219.         int retn;

  220.         if (p == NULL || io_index == NULL || o_base == NULL) {
  221.                 return -1;
  222.         }
  223.         index = *io_index;
  224.         if (index < 0) {
  225.                 return -1;
  226.         }
  227.         skip_space(p, &index);
  228.         if (get_word(p, &index, &start, &len) == 0) {
  229.                 retn = get_token(p + start, len, more, 4);
  230.                 if (retn != -1) {
  231.                         *o_base = base[retn];
  232.                         *io_index = index;
  233.                         return 0;
  234.                 }
  235.         }
  236.         return -1;
  237. }

  238. int get_english_number_bellow_thousand(const char *p, int *io_index, int *o_value)
  239. {
  240.         int index;
  241.         int value;
  242.         int sum;

  243.         if (p == NULL || io_index == NULL || o_value == NULL) {
  244.                 return -1;
  245.         }
  246.         index = *io_index;
  247.         if (index < 0) {
  248.                 return -1;
  249.         }
  250.         if (get_english_number_bellow_hundred(p, &index, &sum) == 0) {
  251.                 if (sum > 0 && sum < 10) {
  252.                         if (skip_word(p, &index, "hundred") == 0) {
  253.                                 sum *= 100;
  254.                                 if (skip_word(p, &index, "and") == 0) {
  255.                                         if (get_english_number_bellow_hundred(p, &index, &value) == -1) {
  256.                                                 return -1;
  257.                                         }
  258.                                         if (value == 0) {
  259.                                                 return -1;
  260.                                         }
  261.                                         sum += value;
  262.                                 }
  263.                         }
  264.                 }
  265.                 *o_value = sum;
  266.                 *io_index = index;
  267.                 return 0;
  268.         }else if (skip_word(p, &index, "a") == 0) {
  269.                 sum = 1;
  270.                 if (skip_word(p, &index, "hundred") == 0) {
  271.                         sum *= 100;
  272.                         if (skip_word(p, &index, "and") == 0) {
  273.                                 if (get_english_number_bellow_hundred(p, &index, &value) == -1) {
  274.                                         return -1;
  275.                                 }
  276.                                 if (value == 0) {
  277.                                         return -1;
  278.                                 }
  279.                                 sum += + value;
  280.                         }
  281.                 }
  282.                 *o_value = sum;
  283.                 *io_index = index;
  284.                 return 0;
  285.         }
  286.         return -1;
  287. }

  288. int get_english_number(const char *p, int *io_index, int *o_value)
  289. {
  290.         int index;
  291.         int value;
  292.         int sum;
  293.         int base;
  294.        
  295.         if (p == NULL || io_index == NULL || o_value == NULL) {
  296.                 return -1;
  297.         }
  298.         index = *io_index;
  299.         if (index < 0) {
  300.                 return -1;
  301.         }
  302.         sum = 0;
  303.         for (;;) {
  304.                 if (get_english_number_bellow_thousand(p, &index, &value) == 0) {
  305.                         if (value == 0) {
  306.                                 break;
  307.                         }
  308.                         if (get_english_number_base(p, &index, &base) == 0) {
  309.                                 value *= base;
  310.                                 if (sum > 0 && value >= sum) {
  311.                                         return -1;
  312.                                 }
  313.                                 sum += value;
  314.                                 continue;
  315.                         }
  316.                         sum += value;
  317.                 }
  318.                 if (sum == 0) {
  319.                         return -1;
  320.                 }
  321.                 break;
  322.         }
  323.         *o_value = sum;
  324.         *io_index = index;
  325.         return 0;
  326. }

  327. int get_operator1(const char *p, int *io_index, int *o_op)
  328. {
  329.         static const char *op_list[] = {
  330.                 "positive",
  331.                 "+",
  332.                 "negative",
  333.                 "-",
  334.         };
  335.         int index;
  336.         int start, len;
  337.         int retn;
  338.        
  339.         if (p == NULL || io_index == NULL || o_op == NULL) {
  340.                 return -1;
  341.         }
  342.         index = *io_index;
  343.         if (index < 0) {
  344.                 return -1;
  345.         }
  346.         skip_space(p, &index);
  347.         if (get_word(p, &index, &start, &len) == 0) {
  348.                 retn = get_token(p + start, len, op_list, 8);
  349.                 if (retn != -1) {
  350.                         *o_op = retn / 2;
  351.                         *io_index = index;
  352.                         return 0;
  353.                 }
  354.         }
  355.         return -1;
  356. }

  357. int get_operator2(const char *p, int *io_index, int *o_op)
  358. {
  359.         static const char *op_list[] = {
  360.                 "plus",
  361.                 "+",
  362.                 "minus",
  363.                 "-",
  364.                 "multiply",
  365.                 "*",
  366.                 "divide",
  367.                 "/",
  368.         };
  369.         int index;
  370.         int start, len;
  371.         int retn;

  372.         if (p == NULL || io_index == NULL || o_op == NULL) {
  373.                 return -1;
  374.         }
  375.         index = *io_index;
  376.         if (index < 0) {
  377.                 return -1;
  378.         }
  379.         skip_space(p, &index);
  380.         if (get_word(p, &index, &start, &len) == 0) {
  381.                 retn = get_token(p + start, len, op_list, 8);
  382.                 if (retn != -1) {
  383.                         if ((retn & 1) == 0) {
  384.                                 skip_word(p, &index, "with");
  385.                         }
  386.                         *o_op = retn / 2;
  387.                         *io_index = index;
  388.                         return 0;
  389.                 }
  390.         }
  391.         return -1;
  392. }

  393. int get_arab_number(const char *p, int *io_index, int *o_value)
  394. {
  395.         int index;
  396.         int value;

  397.         if (p == NULL || io_index == NULL || o_value == NULL) {
  398.                 return -1;
  399.         }
  400.         index = *io_index;
  401.         if (index < 0) {
  402.                 return -1;
  403.         }
  404.         skip_space(p, &index);
  405.         if (isdigit(p[index])) {
  406.                 value = 0;
  407.                 do {
  408.                         value = value * 10 + p[index] - '0';
  409.                         index++;
  410.                 }while (isdigit(p[index]));
  411.                 *o_value = value;
  412.                 *io_index = index;
  413.                 return 0;
  414.         }
  415.         return -1;
  416. }

  417. int get_number(const char *p, int *io_index, int *o_value)
  418. {
  419.         int index;
  420.         int value;

  421.         if (p == NULL || io_index == NULL || o_value == NULL) {
  422.                 return -1;
  423.         }
  424.         index = *io_index;
  425.         if (index < 0) {
  426.                 return -1;
  427.         }
  428.         if (get_english_number(p, &index, &value) == 0
  429.                 || get_arab_number(p, &index, &value) == 0) {
  430.                 *o_value = value;
  431.                 *io_index = index;
  432.                 return 0;
  433.         }
  434.         return -1;
  435. }

  436. int get_oprand(const char *p, int *io_index, int *o_value)
  437. {
  438.         int index;
  439.         int op;
  440.         int d1;
  441.         int result;

  442.         if (p == NULL || io_index == NULL || o_value == NULL) {
  443.                 return -1;
  444.         }
  445.         index = *io_index;
  446.         if (index < 0) {
  447.                 return -1;
  448.         }
  449.         /* one oprand operation */
  450.         if (get_operator1(p, &index, &op) == 0) {
  451.                 if (get_number(p, &index, &d1) != 0) {
  452.                         return -1;
  453.                 }
  454.                 switch (op) {
  455.                 case 0:
  456.                         result = d1;
  457.                         break;
  458.                 case 1:
  459.                         result = -d1;
  460.                         break;
  461.                 default:
  462.                         return -1;
  463.                 }
  464.         }else {
  465.                 if (get_number(p, &index, &result) != 0) {
  466.                         return -1;
  467.                 }
  468.         }
  469.         *o_value = result;
  470.         *io_index = index;
  471.         return 0;
  472. }

  473. int get_end(const char *p, int *io_index)
  474. {
  475.         int index;

  476.         if (p == NULL || io_index == NULL) {
  477.                 return -1;
  478.         }
  479.         index = *io_index;
  480.         if (index < 0) {
  481.                 return -1;
  482.         }
  483.         skip_space(p, &index);
  484.         if (p[index] == '\0') {
  485.                 *io_index = index;
  486.                 return 0;
  487.         }
  488.         return -1;
  489. }

  490. int caculate(const char *exp, int *o_value)
  491. {
  492.         int op; /* operator */
  493.         int d1, d2; /* oprand number */
  494.         int result; /* store the expression result */
  495.         int index;

  496.         if (exp == NULL || o_value == NULL) {
  497.                 return -1;
  498.         }
  499.         index = 0;
  500.         if (get_oprand(exp, &index, &result) == -1) {
  501.                 return -1;
  502.         }
  503.         /* conjunction operation */
  504.         while (get_end(exp, &index) == -1) {
  505.                 /* two oprands operation */
  506.                 d1 = result;
  507.                 if (get_operator2(exp, &index, &op) == -1) {
  508.                         return -1;
  509.                 }
  510.                 if (get_oprand(exp, &index, &d2) == -1) {
  511.                         return -1;
  512.                 }
  513.                 switch (op) {
  514.                 case 0:
  515.                         result = d1 + d2;
  516.                         break;
  517.                 case 1:
  518.                         result = d1 - d2;
  519.                         break;
  520.                 case 2:
  521.                         result = d1 * d2;
  522.                         break;
  523.                 case 3:
  524.                         if (d2 == 0) {
  525.                                 return -1;
  526.                         }
  527.                         result = d1 / d2;
  528.                         break;
  529.                 default:
  530.                         return -1;
  531.                 }
  532.         }
  533.         *o_value = result;
  534.         return 0; /* end of conjunction */
  535. }

  536. int read_line(char *buff, int buf_len)
  537. {
  538.         int len;

  539.         if (buff == NULL || buf_len <= 0) {
  540.                 return -1;
  541.         }
  542.         for (;;) {
  543.                 if (fgets(buff, buf_len, stdin) == NULL) {
  544.                         return -1;
  545.                 }
  546.                 len = strlen(buff) - 1;
  547.                 if (buff[len] == '\n') {
  548.                         buff[len] = '\0';
  549.                         return 0;
  550.                 }
  551.                 /* check for last not terminated line in file */
  552.                 if (fgets(buff, buf_len, stdin) == NULL) {
  553.                         return 0;
  554.                 }
  555.                 /* line length is greater than buffer */
  556.                 /* skip rest line content */
  557.                 for (;;) {
  558.                         len = strlen(buff) - 1;
  559.                         if (buff[len] == '\n') {
  560.                                 return -2; /* buffer overflow, skip the whole line */
  561.                         }
  562.                         if (fgets(buff, buf_len, stdin) == NULL) {
  563.                                 return -1;
  564.                         }
  565.                 }
  566.         }
  567. }

  568. int main(void)
  569. {
  570.         char cmd_line[1024];
  571.         int result;

  572.         puts("English Caculator");
  573.         puts("Enter an expression");
  574.         puts("Ctrl-Z to exit\n");
  575.         for (;;) {
  576.                 printf(": ");
  577.                 switch (read_line(cmd_line, sizeof(cmd_line))) {
  578.                 case 0:
  579.                         break;
  580.                 default:
  581.                 case -1:
  582.                         puts("");
  583.                         return 0;
  584.                 case -2:
  585.                         puts("Buffer Overflow");
  586.                         continue;
  587.                 }
  588.                 if (caculate(cmd_line, &result) == 0) {
  589.                         printf("'%s' = %d\n", cmd_line, result);
  590.                 }else {
  591.                         printf("'%s' = E, Invalid Expression\n", cmd_line);
  592.                 }
  593.         }
  594. }
复制代码

论坛徽章:
11
未羊
日期:2013-12-16 12:45:4615-16赛季CBA联赛之青岛
日期:2016-04-11 19:17:4715-16赛季CBA联赛之广夏
日期:2016-04-06 16:34:012015亚冠之卡尔希纳萨夫
日期:2015-11-10 10:04:522015亚冠之大阪钢巴
日期:2015-07-30 18:29:402015亚冠之城南
日期:2015-06-15 17:56:392015亚冠之卡尔希纳萨夫
日期:2015-05-15 15:19:272015亚冠之山东鲁能
日期:2015-05-14 12:38:13金牛座
日期:2014-12-04 15:34:06子鼠
日期:2014-10-16 13:40:4715-16赛季CBA联赛之八一
日期:2016-07-22 09:41:40
23 [报告]
发表于 2011-08-10 12:13 |只看该作者
真闲

论坛徽章:
0
24 [报告]
发表于 2011-08-10 21:23 |只看该作者
回复 1# toddytao


    我觉的应该分两步分析,首先把英文转化成数字和加减乘除符号,然后使用数字和加减乘除的计算器就容易实现了。

论坛徽章:
0
25 [报告]
发表于 2011-08-11 15:52 |只看该作者
回复 24# sudayly


大哥。。。我的思路和你差不多。。已经完成了。。。等了好久没有回复。。。我自己写了个。。。

论坛徽章:
0
26 [报告]
发表于 2011-08-11 15:53 |只看该作者
回复 22# cobras


大哥。。谢谢你的回复。。。辛苦了。。。。我已经完成了。。自己写了个。。

论坛徽章:
0
27 [报告]
发表于 2011-08-14 20:10 |只看该作者
不错,C很强大啊
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP