签到

06月21日
尚未签到

共有回帖数 0

    十万个为什么

    等级:
    命令行计算器
    /*
     Name: Command Line Calculator Version 1.0.1
     Copyright: akuma@tds
     Author: akuma@tds
     Date: 06/01/05 03:00
     Description:
       This is a free software distributed
       under The free beer license version 1.02
    */

    #include stdio.h
    #include stdlib.h
    #include errno.h
    #include limits.h
    #include string.h

    int isNumber(const char *buf);
    void display_license(void);
    void display_copyright(void);
    void display_help(void);
    int process_cmd(char *cmd);
    void get_cmd(char *buf, int buf_size);

    const char *delimiters = " nt,;";

    const char *fs_d = "%ld";

    const char *s_prompt = "# ";
    const char *s_acc_mode_prompt = " + ";

    const char *s_final_result = "n[result] = %ldn";
    const char *s_result = "[result] = %ld, [operand] = %ldn";
    const char *s_clear = "[result] and [operand] had been set to zeron";
    const char *s_acc_mode =
    "[+] accumulation mode activated, enter zero to exitn";
    const char *s_acc_exit = "[-] exit accumulation moden";
    const char *s_trc_mode = "[+] trace mode activatedn";
    const char *s_trc_exit = "[-] trace mode offn";

    const char *s_warning_2_num =
    "[warning] more than one numbers entered, set operand equal to the first onen";
    const char *s_warning_2_cmd =
    "[warning] entered more than one command, only the first one will be usedn";
    const char *s_warning_mt_2_cmd =
    "[warning] too much command, every entry except first two will be discardedn";
    const char *s_warning_ofr_num =  
    "[warning] the number is out of range, reset operand to zeron";

    const char *s_error_bad_num =
    "[error]   unrecognizable number enteredn";
    const char *s_error_unknown =
    "[error]   unknown commandn";
    const char *s_error_dbz =
    "[error]   %ld cannot be devided by zeron";

    const char *s_copyright =
    "Command Line Calculator 1.0.1 - copyright © 2005 akuma@tdsn"
    "- This is a free software distributed under The free beer license version 1.02n"
    "- enter h for help, L for license information, q to exitn"
    "n";

    /* 下面继续 */
    const char *s_license =
    "FREE BEER LICENSE VERSION 1.02n"
    "The free beer license is a license to give free software to you and freen"
    "beer (in)to the author(s).n"
    "Your rights are :n"
    "0. You can use this piece of software in anyway you like.n"
    "1. You can redistribute this piece of software in source form or inn"
    " compiled form.n"
    "2. You can alter the source to your needs and redistribute the alteredn"
    " source in source form or in compiled form.n"
    "However :n"
    "0. This program is provided without warranty of any kind. So, if itn"
    " breaks anything, for example itself, it is up to you.n"
    "1. If you redistribute this piece of software, you are not allowed ton"
    " charge money for this piece of software itself.n"
    "2. If you redistribute this pieces of software in binary form, you mustn"
    " supply the source code as well.n"
    "3. If you redistribute this software, modified or not, you mustn"
    " redistribute it under this license and you must include the name ofn"
    " the original author(s) and you must point out where the originaln"
    " source can be obtained.n"
    "4. If you use this piece of software frequently, and you think it isn"
    " worth a couple of dollars, you are not allowed to send the authorn"
    " anything else than beer or means that provide facilities to get beern"
    " into the author(s) (i.e. openers, glasses).n";

    const char *s_helpmsg =
    "enter: # [operator] [number] -------- (1)n"
    " or # [number] [operator] -------- (2)n"
    " or # [command¦operator¦number] -------- (3)n"
    " [command]n"
    " Q¦q (3) : exit this programn"
    " H¦h (3) : display this messagen"
    " L¦l (3) : display the license informationn"
    " S¦s (3) : enter accumulation moden"
    " T¦t (3) : toggle trace displayn"
    " C¦c (3) : reset the value of result and operandn"
    " [operator]n"
    " ? (3) : display the value of result and operandn"
    " + (1¦2) : add [number] to the resultn"
    " (3) : add operand to the resultn"
    " - (1) : result - [number]n"
    " (2) : [number] - resultn"
    " * (1¦2) : multiply the result by [number]n"
    " (3) : multiply the result by operandn"
    " / (1) : result / [number]n"
    " (2) : [number] / resultn"
    " (3) : result / operandn"
    " = (1¦2) : assign [number] to he resultn"
    " (3) : make result equal to operandn"
    " [number] : set operand = [number], prefix 0x for Hex, 0 for Octn";

    /* 下面继续 */
    #ifdef _MSC_VER
    /* Stupid M$ compiler doesn't allow me to define a char array */
    /* with a const int. So I have to use macro here for M$ C*/
    #define max_buffer 81
    #else
    const int max_buffer = 81;
    #endif

    int isNumber(const char *buf)
    {
    int i = 0;
    if (('-' == buf[0] ¦¦ '+' == buf[0]))
    i++;
    if ('' == buf) {
    return 0;
    } else if ('0' == buf && ('X' == buf[i+1]) ¦¦ ('x' == buf[i+1])) {
    i += 2;
    while (buf)
    if (!isxdigit(buf[i++]))
    return 0;
    } else if ('0' == buf) {
    while (buf) {
    if (!isdigit(buf) ¦¦ buf  '7')
    return 0;
    i++;
    }
    } else {
    while (buf)
    if (!isdigit(buf[i++]))
    return 0;
    }
    return 1;
    }

    long read_value(const char *buf)
    {
    long ret = 0;
    ret = strtol(buf, NULL, 0);
    if (ERANGE == errno && ((LONG_MAX == ret) ¦¦ (LONG_MIN == ret))) {
    printf(s_warning_ofr_num);
    ret = 0;
    }
    return ret;
    }

    void display_license(void)
    {
    printf(s_license);
    }

    /* 下面继续 */
    void display_copyright(void)
    {
    printf(s_copyright);
    }

    void display_help(void)
    {
    printf(s_helpmsg);
    }

    int process_cmd(char *cmd)
    {
    static long result = 0;
    static long operand = 0;
    static int trace_mode = 0;
    char buf[max_buffer];
    char * temp_p;
    char command = ' ';
    int post = 0;
    if (NULL == (temp_p = strtok(cmd, delimiters)))
    return 1;
    if (isNumber(temp_p)) {
    operand = read_value(temp_p);
    if (NULL == (temp_p = strtok(NULL, delimiters)))
    command = ' ';
    else if (!isNumber(temp_p)) {
    post = 1;
    command = temp_p[0];
    if ('' != temp_p[1] && !isdigit(temp_p[0]))
    command = '';
    } else {
    printf(s_warning_2_num);
    }
    } else {
    command = temp_p[0];
    if ('' != temp_p[1] && !isdigit(temp_p[0]))
    command = '';
    post = 0;
    if (NULL != (temp_p = strtok(NULL, delimiters)))
    if (isNumber(temp_p))
    operand = read_value(temp_p);
    else
    printf(s_warning_2_cmd);
    }

    if (NULL != (temp_p = strtok(NULL, delimiters)))
    printf(s_warning_mt_2_cmd);


    /* 下面继续 */

    switch (command) {
    case ' ':
    break;
    case 'h':
    case 'H':
    display_help();
    break;
    case 'l':
    case 'L':
    display_license();
    break;
    case 't':
    case 'T':
    trace_mode = !trace_mode;
    printf((trace_mode) ? s_trc_mode : s_trc_exit);
    break;
    case '?':
    printf(s_result, result, operand);
    break;
    case 'q':
    case 'Q':
    printf(s_final_result, result);
    return 0;
    case 'c':
    case 'C':
    result = operand = 0;
    printf(s_clear);
    break;
    case 's':
    case 'S':
    printf(s_acc_mode);
    do {
    if (trace_mode)
    printf(fs_d, result);
    printf(s_acc_mode_prompt);
    fgets(buf, max_buffer - 1, stdin);
    operand = read_value(buf);
    result += operand;
    } while (operand);
    printf(s_acc_exit);
    break;
    case '+':
    result += operand;
    break;
    case '-':
    if (post)
    result = operand - result;
    else
    result -= operand;
    break;
    case '*':
    result *= operand;
    break;
    case '/':
    if (post)
    result = operand / result;
    else if (operand == 0)
    printf(s_error_dbz, result);
    else
    result /= operand;
    break;
    case '=':
    result = operand;
    break;
    default:
    if (isdigit(command))
    printf(s_error_bad_num);
    else
    printf(s_error_unknown);
    break;
    }

    /* 下面继续 */
    if (trace_mode)
    switch (command) {
    case '?':
    case 'h':
    case 'H':
    case 'l':
    case 'L':
    break;
    default:
    printf(s_result, result, operand);
    }
    return 1;
    }

    void get_cmd(char *buf, int buf_size)
    {
    printf(s_prompt);
    fgets(buf, buf_size - 1, stdin);
    }

    int main(int argc, char *argv[])
    {
    char input_buffer[max_buffer];
    display_copyright();
    get_cmd(input_buffer, max_buffer);
    while (process_cmd(input_buffer))
    get_cmd(input_buffer, max_buffer);
    return 0;
    }

    楼主 2016-02-12 15:38 回复

共有回帖数 0
  • 回 帖
  • 表情 图片 视频
  • 发表

登录直线网账号

Copyright © 2010~2015 直线网 版权所有,All Rights Reserved.沪ICP备10039589号 意见反馈 | 关于直线 | 版权声明 | 会员须知