c语言:各种进制之间的相互转换

qwz_ss 2011-12-27 07:15:00
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define N 32
int MD(int s,char *str)
{
int m=0;
while(*str){
if(*str>='a'&&*str<='f')
m=s*m+*str-'a'+10;
else if(*str>='A'&&*str<='F')
m=s*m+*str-'A'+10;
else
m=s*m+*str-'0';
str++;
}
return m;
}

void reverse(char *s)
{
int i,j;
char c;
for(i=0,j=strlen(s)-1;i<j;i++,j--){
c=s[i];
s[i]=s[j];
s[j]=c;
}

}
char * exch(int srcs,char *str,int s)
{
int m,i,num;
char *t=(char *)malloc(N);
i=0;
m=MD(srcs,str);

do{
if(m%s<10)
t[i++]=m%s+'0';
else
t[i++]=m%s-10+'A';
}while((m/=s)!=0);
if(s>=10){
t[i++]='X';
t[i]='0';
}
reverse(t);
return t;

}



int main(void)
{
int srcs,ds;
char s[N];
#if 1
printf("给出一个整数:\n");
scanf("%s",s);
printf("它的进制是:\n");
scanf("%d",&srcs);
printf("十进制结果是:\n");
printf("%d\n\n",MD(srcs,s));
#endif
printf("给出一个整数:\n");
scanf("%s",s);
printf("它的进制是:\n");
scanf("%d",&srcs);
printf("要转换成的进制是:\n");
scanf("%d",&ds);
printf("转换之后结果是:\n");
printf("%s\n",exch(srcs,s,ds));
return 0;
}
...全文
647 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
qq120848369 2012-01-14
  • 打赏
  • 举报
回复
strtol很简单啊.
JackBurd 2012-01-13
  • 打赏
  • 举报
回复
6L的
static unsigned long __cdecl strtoxl (
_locale_t plocinfo,
const char *nptr,
const char **endptr,
int ibase,
int flags
)
是什么意思啊?
赵4老师 2012-01-12
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 jixingzhong 的回复:]
看看 strtol 的实现吧,它的最后一个参数是数值的进制。
[/Quote]
C:\Program Files\Microsoft Visual Studio 10.0\VC\crt\src\strtol.c
...
static unsigned long __cdecl strtoxl (
_locale_t plocinfo,
const char *nptr,
const char **endptr,
int ibase,
int flags
)
{
const char *p;
char c;
unsigned long number;
unsigned digval;
unsigned long maxval;
_LocaleUpdate _loc_update(plocinfo);

/* validation section */
if (endptr != NULL)
{
/* store beginning of string in endptr */
*endptr = (char *)nptr;
}
_VALIDATE_RETURN(nptr != NULL, EINVAL, 0L);
_VALIDATE_RETURN(ibase == 0 || (2 <= ibase && ibase <= 36), EINVAL, 0L);

p = nptr; /* p is our scanning pointer */
number = 0; /* start with zero */

c = *p++; /* read char */
while ( _isspace_l((int)(unsigned char)c, _loc_update.GetLocaleT()) )
c = *p++; /* skip whitespace */

if (c == '-') {
flags |= FL_NEG; /* remember minus sign */
c = *p++;
}
else if (c == '+')
c = *p++; /* skip sign */

if (ibase < 0 || ibase == 1 || ibase > 36) {
/* bad base! */
if (endptr)
/* store beginning of string in endptr */
*endptr = nptr;
return 0L; /* return 0 */
}
else if (ibase == 0) {
/* determine base free-lance, based on first two chars of
string */
if (c != '0')
ibase = 10;
else if (*p == 'x' || *p == 'X')
ibase = 16;
else
ibase = 8;
}

if (ibase == 0) {
/* determine base free-lance, based on first two chars of
string */
if (c != '0')
ibase = 10;
else if (*p == 'x' || *p == 'X')
ibase = 16;
else
ibase = 8;
}

if (ibase == 16) {
/* we might have 0x in front of number; remove if there */
if (c == '0' && (*p == 'x' || *p == 'X')) {
++p;
c = *p++; /* advance past prefix */
}
}

/* if our number exceeds this, we will overflow on multiply */
maxval = ULONG_MAX / ibase;


for (;;) { /* exit in middle of loop */
/* convert c to value */
if ( __ascii_isdigit_l((int)(unsigned char)c, _loc_update.GetLocaleT()) )
digval = c - '0';
else if ( __ascii_isalpha_l((int)(unsigned char)c, _loc_update.GetLocaleT()) )
digval = __ascii_toupper(c) - 'A' + 10;
else
break;
if (digval >= (unsigned)ibase)
break; /* exit loop if bad digit found */

/* record the fact we have read one digit */
flags |= FL_READDIGIT;

/* we now need to compute number = number * base + digval,
but we need to know if overflow occured. This requires
a tricky pre-check. */

if (number < maxval || (number == maxval &&
(unsigned long)digval <= ULONG_MAX % ibase)) {
/* we won't overflow, go ahead and multiply */
number = number * ibase + digval;
}
else {
/* we would have overflowed -- set the overflow flag */
flags |= FL_OVERFLOW;
if (endptr == NULL) {
/* no need to keep on parsing if we
don't have to return the endptr. */
break;
}
}

c = *p++; /* read next digit */
}

--p; /* point to place that stopped scan */

if (!(flags & FL_READDIGIT)) {
/* no number there; return 0 and point to beginning of
string */
if (endptr)
/* store beginning of string in endptr later on */
p = nptr;
number = 0L; /* return 0 */
}
else if ( (flags & FL_OVERFLOW) ||
( !(flags & FL_UNSIGNED) &&
( ( (flags & FL_NEG) && (number > -LONG_MIN) ) ||
( !(flags & FL_NEG) && (number > LONG_MAX) ) ) ) )
{
/* overflow or signed overflow occurred */
errno = ERANGE;
if ( flags & FL_UNSIGNED )
number = ULONG_MAX;
else if ( flags & FL_NEG )
number = (unsigned long)(-LONG_MIN);
else
number = LONG_MAX;
}

if (endptr != NULL)
/* store pointer to char that stopped the scan */
*endptr = p;

if (flags & FL_NEG)
/* negate result if there was a neg sign */
number = (unsigned long)(-(long)number);

return number; /* done. */
}
...
JackBurd 2012-01-12
  • 打赏
  • 举报
回复
你的代码三点问题:(1)应改为char *t=(char *)malloc(N*sizeof(char));这表示分配了n个char型
数据的内存。
(2)应该在字符串t后加结束符即t[++i]='\0'。
(3)你的exch()函数实际上是把该字符串转换成了16进的,而非2,8,10,16中任-种。
把(1)(2)改正后没问题了,如果你想转换成任意进制,参照(3)修改。
柯本 2011-12-27
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 jixingzhong 的回复:]
看看 strtol 的实现吧,它的最后一个参数是数值的进制。
[/Quote]
++
strtol支持2~36进制转换
对应是的itoa
柯本 2011-12-27
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 jixingzhong 的回复:]
看看 strtol 的实现吧,它的最后一个参数是数值的进制。
[/Quote]
++
strtol支持2~36进制转换
对应是的itoa
柯本 2011-12-27
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 jixingzhong 的回复:]
看看 strtol 的实现吧,它的最后一个参数是数值的进制。
[/Quote]
++
strtol支持2~36进制转换
对应是的itoa
jixingzhong 2011-12-27
  • 打赏
  • 举报
回复
看看 strtol 的实现吧,它的最后一个参数是数值的进制。

69,369

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧