/* 进制转换程序 ConvertNumber Version 0.6.3 #20060215
* a Bunki program. Kikistar SoftStyle.
* All Rights Died, All Freedom Reserved.
* http://kikistar.com
* E-mail: kikistar.com@gmail.com
*/
#include <stdio.h>
#include <stdlib.h> /* the strtol(), k&r p252 */
#include <ctype.h>
#include <string.h>
void getindex(int n, char index[]);
int getnumber(char stringin[], int base);
void showresult(int base);
void intton(int numin, int baseout, char numout[]);
void goback(int n);
void insertspt(char s[], char c, int a);
#define INDEXWIDTH 3 /* two letters and a '/0' */
int main()
{
int e;
char index[INDEXWIDTH];
printf("/n");
printf("进制转换 ConverNumber 0.6.3 #20060215/n");
printf("---------------------------------------------------/n");
printf("| 本程序用以对数字进行进制转换。 |/n");
printf("| |/n");
printf("| 请先选择一种进制,然后输入一个数字, |/n");
printf("| 我会把这个数字转换成其它进制数。 |/n");
printf("---------------------------------------------------/n");
e = 1;
while (e == 1) {
printf("/n/t/tA. 十进制/t(10)/n");
printf("/t/tB. 十六进制/t(16)/n");
printf("/t/tC. 八进制/t(8)/n");
printf("/t/tD. 二进制/t(2)/n");
printf("/n/t/tE. 安全出口/t(0)/n");
printf("/n请选择一种进制(然后按回车键):");
getindex(INDEXWIDTH, index);
if (strcmp(index,"a")==0||strcmp(index,"A")==0)
showresult(10);
else if(strcmp(index,"b")==0||strcmp(index,"B")==0)
showresult(16);
else if(strcmp(index,"c")==0||strcmp(index,"C")==0)
showresult(8);
else if(strcmp(index,"d")==0||strcmp(index,"D")==0)
showresult(2);
else if(strcmp(index,"e") == 0
|| strcmp(index,"E") == 0
|| strcmp(index,"0") == 0)
e = 0;
else if ((isdigit(index[0]) && isdigit(index[1]))
|| (isdigit(index[0]) && index[1] == '/0'))
{
if (atoi(index) < 2 || atoi(index) > 36){
printf("/n/7");
printf("/t--------------------------------------/n");
printf("/t| Error! |/n");
printf("/t| 我对不起你,我只能转换2至36进制数。|/n");
printf("/t--------------------------------------/n");
}
else
showresult(atoi(index));
}
else {
printf("/n/7");
printf("/t-------------------------------------------------/n");
printf("/t| Error! |/n");
printf("/t| 请输入一个字母 'a', 'b', 'c', 'd', 或 'e' |/n");
printf("/t| 或者输入一个数字,例如 32(表示三十二进制数) |/n");
printf("/t| 然后按回车键。 |/n");
printf("/t-------------------------------------------------/n");
}
}
printf("/n/t感谢你使用本程序!欢迎来blog来mail交流。/n");
printf("/thttp://my.opera.com/419//n");
printf("/tkikistar.com@gmail.com/n/n");
return 0;
}
void getindex(int width, char index[])
{
int i;
char c;
/* 过滤所输入的全部char,记录前n个字符 */ /* k&r p18 */
for (i=0; (c = getchar()) != '/n'; ++i)
if (i < width)
index[i] = c;
index[i] = '/0';
}
void showresult(int base)
{
int i;
int numberin;
char stringin[30];
char numberout[30];
printf("/n请输入一个%2d 进制数:", base);
numberin = getnumber(stringin, base);
if (numberin < 0) /* 出错,getnumber己给出错误提示,所以这里什么也不做 */
;
else {
numberin = strtol(stringin, NULL, base);
if (numberin == 2147483647){
printf("/n/7");
printf("/t-------------------------------------/n");
printf("/t| 注意! |/n");
printf("/t| 以下是数字是我能处理的最大数了。 |/n");
printf("/t-------------------------------------/n");
intton(2147483647, base, stringin);
}
printf("/n/t/t %s (%d)/n", stringin, base);
for (i = 16; i > 1; i /= 2)
if (i == base || i == 4)
;
else {
intton(numberin, i, numberout);
insertspt(numberout, ' ', 4);
printf("/t/t= %s (%d)/n", numberout, i);
}
printf("/n");
if (base != 10){
intton(numberin, 10, numberout);
insertspt(numberout, ',', 3);
printf("/t/t= %s (10)/n", numberout);
}
if (base != 36){
intton(numberin, 36, numberout);
printf("/t/t= %s (36)/n", numberout);
}
goback(0);
}
}
int getnumber(char stringin[], int base)
{
char number[1000];
char wrong;
int i, j;
j = 0;
for (i=0; ((number[i]=getchar()) != '/n'); ++i)
if (base >= 2 && base <= 10) {
if (number[i] < '0' || number[i] >= base+'0'){
wrong = number[i];
j = 1;
goback(1);
break;
}
}
else if (base >= 11 && base <= 36) {
if (isalpha(number[i]) && toupper(number[i]) < base - 10 + 'A')
;
else if (isdigit(number[i]))
;
else {
wrong = number[i];
j = 1;
goback(1);
break;
}
}
else {
printf("Error03!/n");
printf("Sorry, I can only convert a number base from 2 to 36.");
}
if (j == 1) {
printf("/n/7");
printf("/t------------------------------------------/n");
printf("/t| Error! |/n");
switch (wrong){
case '.':
printf("/t| 不好意思啦,我不会转换带小数点的数字 |/n");
break;
case ' ':
printf("/t| 请不要输入空格,多谢合作! |/n");
break;
default :
printf("/t| %2d进制数里没有 '%c'. |/n", base, wrong);
}
printf("/t| |/n");
printf("/t| Tips: 不输入数字直接按回车键可回主菜单 |/n");
printf("/t------------------------------------------/n");
showresult(base);
return -1;
}
number[i] = '/0'; /* k&r p29, p30 */
strcpy(stringin, number);
if (i == 0)
return -1;
else
return strtol(stringin, NULL, base);
}
/* 算法参考 <<C语言实用程序设计100例>> 人民邮电出版社
*
* 本函数把 numin(一个十进制数) 转换成 numout(baseout进制数),
* baseout的范围是2-36
*
* k&r exercise 3-5 p64
*/
void intton(int numin, int baseout, char numout[])
/* 用函数的参数“返回”数,k&r Section 1 */
{
int i, j;
for (i = 0; numin != 0; ++i) {
j = numin % baseout;
if (j > 9)
numout[i] = j + 'A' - 10;
else
numout[i] = j + '0';
numin /= baseout;
}
/* reverses numout[] */ /* k&r Exercise 1-19 */
for (j = 0; j <= i/2-1; ++j) {
numout[i] = numout[j]; /* n[i] as temp */
numout[j] = numout[i-1-j]; /* n[i-1] is the last char */
numout[i-1-j] = numout[i];
}
numout[i] = '/0'; /* k&r p30 */
}
void goback(int n) {
if (n == 1)
while (getchar() != '/n')
;
else {
printf("/n 请按回车键继续.../n");
while (getchar() != '/n')
;
}
}
/* insert seperaters in n
insert c into s by every a charaters
*/
/* 插入分隔符 */
void insertspt(char s[], char c, int a)
{
int i, j, k, l;
j = strlen(s);
i = j + j / a; /* the new size of s */
if (j % a == 0) /* 避免在数字开头加分隔符 */
--i;
s[i] = '/0';
for (k = i-j; k > 0; --k){
for (l = a ; l > 0; --l)
s[(i--)-1] = s[(j--)-1]; /* array subscripts start at zero */
s[(i--)-1] = c;
}
}