共有回帖数 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 回复
Copyright © 2010~2015 直线网 版权所有,All Rights Reserved.沪ICP备10039589号
意见反馈 |
关于直线 |
版权声明 |
会员须知