level 1
/* 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
#include
#include
#include
#include
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 = " \n\t,;";const char *fs_d = "%ld";const char *s_prompt = "# ";const char *s_acc_mode_prompt = " + ";const char *s_final_result = "\n[result] = %ld\n";const char *s_result = "[result] = %ld, [operand] = %ld\n";const char *s_clear = "[result] and [operand] had been set to zero\n";const char *s_acc_mode ="[+] accumulation mode activated, enter zero to exit\n";const char *s_acc_exit = "[-] exit accumulation mode\n";const char *s_trc_mode = "[+] trace mode activated\n";const char *s_trc_exit = "[-] trace mode off\n";const char *s_warning_2_num ="[warning] more than one numbers entered, set operand equal to the first one\n";const char *s_warning_2_cmd ="[warning] entered more than one command, only the first one will be used\n";const char *s_warning_mt_2_cmd ="[warning] too much command, every entry except first two will be discarded\n";const char *s_warning_ofr_num = "[warning] the number is out of range, reset operand to zero\n";const char *s_error_bad_num ="[error] unrecognizable number entered\n";const char *s_error_unknown ="[error] unknown command\n";const char *s_error_dbz ="[error] %ld cannot be devided by zero\n";const char *s_copyright ="Command Line Calculator 1.0.1 - copyright © 2005 akuma@tds\n""- This is a free software distributed under The free beer license version 1.02\n""- enter h for help, L for license information, q to exit\n""\n";/* 下面继续 */
2005年01月18日 09点01分
1
level 1
const char *s_license ="FREE BEER LICENSE VERSION 1.02\n""The free beer license is a license to give free software to you and free\n""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 in\n"" compiled form.\n""2. You can alter the source to your needs and redistribute the altered\n"" source in source form or in compiled form.\n""However :\n""0. This program is provided without warranty of any kind. So, if it\n"" breaks anything, for example itself, it is up to you.\n""1. If you redistribute this piece of software, you are not allowed to\n"" charge money for this piece of software itself.\n""2. If you redistribute this pieces of software in binary form, you must\n"" supply the source code as well.\n""3. If you redistribute this software, modified or not, you must\n"" redistribute it under this license and you must include the name of\n"" the original author(s) and you must point out where the original\n"" source can be obtained.\n""4. If you use this piece of software frequently, and you think it is\n"" worth a couple of dollars, you are not allowed to send the author\n"" anything else than beer or means that provide facilities to get beer\n"" 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 program\n"" H¦h (3) : display this message\n"" L¦l (3) : display the license information\n"" S¦s (3) : enter accumulation mode\n"" T¦t (3) : toggle trace display\n"" C¦c (3) : reset the value of result and operand\n"" [operator]\n"" ? (3) : display the value of result and operand\n"" + (1¦2) : add [number] to the result\n"" (3) : add operand to the result\n"" - (1) : result - [number]\n"" (2) : [number] - result\n"" * (1¦2) : multiply the result by [number]\n"" (3) : multiply the result by operand\n"" / (1) : result / [number]\n"" (2) : [number] / result\n"" (3) : result / operand\n"" = (1¦2) : assign [number] to he result\n"" (3) : make result equal to operand\n"" [number] : set operand = [number], prefix 0x for Hex, 0 for Oct\n";/* 下面继续 */
2005年01月18日 09点01分
2
level 1
#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#elseconst int max_buffer = 81;#endifint isNumber(const char *buf){ int i = 0; if (('-' == buf[0] ¦¦ '+' == buf[0])) i++; if ('\0' == buf[i]) { return 0; } else if ('0' == buf[i] && ('X' == buf[i+1]) ¦¦ ('x' == buf[i+1])) { i += 2; while (buf[i]) if (!isxdigit(buf[i++])) return 0; } else if ('0' == buf[i]) { while (buf[i]) { if (!isdigit(buf[i]) ¦¦ buf[i] > '7') return 0; i++; } } else { while (buf[i]) 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);}/* 下面继续 */
2005年01月18日 09点01分
3
level 1
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 ('\0' != temp_p[1] && !isdigit(temp_p[0])) command = '\0'; } else { printf(s_warning_2_num); } } else { command = temp_p[0]; if ('\0' != temp_p[1] && !isdigit(temp_p[0])) command = '\0'; 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);/* 下面继续 */
2005年01月18日 09点01分
4
level 1
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; }/* 下面继续 */
2005年01月18日 09点01分
5
level 1
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;}
2005年01月18日 09点01分
6
level 7
呵呵,辛苦了,百度不用自己分贴子的,你把整个程序粘贴到输入框里,发送后他自己会分开。
2005年01月18日 10点01分
9
level 1
呵呵, 我是学 assiss 的, 我想控制在那里分开.
2005年01月18日 10点01分
10
level 1
在Linux (我用Debian, kernel 2.2.18) 下用 fgets() 读键盘不能很好的处理方向键,反正是示范程序,无所谓啦.
2005年01月18日 10点01分
11
level 9
佩服佩服啊。高手就是不一样。akuma是做什么工作的?
2005年01月18日 10点01分
12
level 1
高手我可不敢当! 要知道山外有山,人上有人啊.我做什么的? 瞎忙活.我只是爱编程序...
2005年01月18日 11点01分
13
level 0
有高手能用数组帮我解决下 send+ more----------- money这个题吗?各个字母不同,求各个字母代表的数字
2006年04月20日 12点04分
18
level 0
error C2106: '=' : left operand must be l-value请问上句话是何意识?
2006年04月26日 13点04分
19