C语言实例教程_命令行计算器
/*
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 = " \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";
/* 下面继续 */ 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";
/* 下面继续 */#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 ('\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);
}
/* 下面继续 */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);
/* 下面继续 */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;
}
编写一个简单的计算器,允许键入表达格式是 :number operator,该程序应能识别+ - * / s q 其中s通知程序键入累加器一个数,q表示结束。
Word教程网 | Excel教程网 | Dreamweaver教程网 | Fireworks教程网 | PPT教程网 | FLASH教程网 | PS教程网 |
HTML教程网 | DIV CSS教程网 | FLASH AS教程网 | ACCESS教程网 | SQL SERVER教程网 | C语言教程网 | JAVASCRIPT教程网 |
ASP教程网 | ASP.NET教程网 | CorelDraw教程网 |