整型和字符数组之间的转换(略带进制的转化)(二)

2014-11-24 02:56:56 · 作者: · 浏览: 5
sign = n;
i = 0;
do
{
s[i++] = abs(n%10) +'0';
}while((n/=10) != 0);
if(sign < 0)
s[i++] = '-';
while(i < w)
s[i++] = ' ';
s[i] = '\0';
reverse(s);
}
复制代码
上面也就是更改的地方,很简单的一个操作,作用就是让输出长度可以自己控制。多余的用空格填补在左边。
引申:
既然我们能将十进制的数转换成十进制形式保存在字符中,那么我们能不能将十进制的数转换成16进制,8进制,2进制等等这些常用的进制数呢? 那么我们可以试一下。
itob: 将整数n转换成以b为底的数
分析下,二进制就是0和1表示的,8进制是0开头的,后面的数是0~7表示的,16进制是0~9 a~f表示的。(A~F暂时不考虑)。那么对于前面的几个数还是可以的,都不超过9,但是到了16进制的时候,那个字符部分,我们可以用‘a’+多出的数,怎么算多出的数,就是超过10的数,最多超过5,也就是到f。看上去还是不太复杂的。那就可以实现实现了,和上面的itoa那个很相似的。
复制代码
void itob(int n,char s[],int b)
{
int i,sign,j;
if((sign = n) < 0)
n = -n; //保证是正数。
i = 0;
do
{
j = n % b;
s[i++] = (j <= 9) j+'0' : j+'a' - 10; //转换过程,一个条件表达式解决。
}while((n/=b) > 0);
if(sign < 0)
s[i++] = '-';
s[i] = '\0';
reverse(s);
}
复制代码
这就解决了这个问题,我们平时在简单的进制转换的时候基本是也是这个方法,只是在处理十六进制的时候有点复杂,那个a~f和A~F的切换,虽然这两个都是可以代表十六进制的,但是我们还是要完美的实现一下,这边还有一个不足的就是对于8进制的数,前面有一个0开头,16进制的有一个0x开头,这个的实现估计也很简单把,添加相应的条件语句就可以了。
补充:
说到了进制了,那就将十六进制,这个较为复杂的一个转换成对应的十进制数。通过十六进制的数字组成的一个字符数组来实现下,这个就大大简化了。我们在输入十六进制和八进制的时候是有对应的格式输入的,%i就是可以实现输入。输出就是分别是x或是o格式输出的。忽略前面的符号标志。这个暂且不讨论,要是这么进行转换的话,讨巧的就是利用格式输出。而对于用直接输入通过细节转换的方法,我目前也就想到用我上面说的那个字符数组来实现,对于直接操作十六进制数这个难度有点大。这些不考虑了,就用字符数组来实现把。从屏幕读入十六进制得数,然后进行判断然后转换。下面是实现的代码。
复制代码
int htoi(char s[])
{
int hexdigit, i, flag,n;
i = 0;
if(s[i] == '0')
{
++i;
if(s[i] == 'x'|| s[i] == 'X')
++i;
}
n = 0;
flag = 1;
for(; flag == 1;++i)
{
if(s[i] >='0' && s[i] <= '9')
hexdigit = s[i]- '0'; //0~9的情况下
else if(s[i] >= 'a' && s[i] <= 'f')
hexdigit = s[i] - 'a' + 10; //a~f的情况下
else if(s[i] >= 'A' && s[i] <= 'F')
hexdigit = s[i] - 'A' +10; //A~F的情况下
else
flag = 0; //什么情况都不是,表明不是一个合格的十六进制。直接退出循环。
if(flag == 1)
n = 16 * n +hexdigit;
}
return n;
}
复制代码
利用字符数组就是能够很清晰的将每个部分的情况都能表示的很清楚,如果用直接格式输入的方法,我们比较难的对一个十六进制的数进行操作,如果直接将十六进制除一个十进制数,那么这个十六进制数处理的结果就会很奇怪,我目前是没有想到如何操作十六进制数来实现这个转换,希望能想到的能交流下。
对于其他的进制之间的转换,大体就是根据这样的一个形式来实现了,高位的一般都是要不断的去乘上要转换的数制的大小就好了。上面红色加粗的部分就是这个的关键部分,如何去理解,可以笔算下,这个相当于嵌套着提取公因数的做法。需要多想想。
reverse函数的补充:
前面在整型转换成字符的时候都有一个逆序的操作,我们在存储时是用的逆序存储的,就是高位存储在后面(要对应数组的构造想)。所以我们要想得到正确的答案,难么逆序是必须要做的,对一个字符数组做逆序,一般有两个方法。
方法一:引入另一个数组,但是好理解。我们利用了string.h里面一个函数strlen(),他返回的是数组有效的字符的长度,也就是忽略了最后的'\0'。这个就是让处理变得简单了。
复制代码
void reverse(char from[],char to[])
{
int i,j;
j = strlen(from);
for(i = 0;i < strlen(from);i++)
to[i] = from[--j];
to[i] = '\0';
}
复制代码
方法二:对于方法一,我们可以继续优化下,可以之用到要逆序的数组,而不需要用到另一个数组,还有就是上面的处理还是不到位的,没有对空白字符的处理,'\n'是要放在最后的。所以下面是一个比较完整而且实用的方法
复制代码
1 void reverse(char s[])
2 {
3 int i,j,temp;
4 i = 0;
5 while(s[i] != '\0') //将i移动到最后
6 ++i;
7 --i; //看倒数第二个是不是换行符
8 if(s[i] == '\n')
9 --i; //是的话就向前一个。
10 j = 0;
11 while(j < i) //排除了最后的“无效”字符,将前面的数对调,这个操作应该很熟悉的
12 {
13 temp = s[j];
14 s[j] = s[i];
15 s[i] = temp;
16 }
17 }
复制代码
说了这么多,也就是为了说明一下,在自己实现类型转换的时