我有一个十六进制格式为“0d76”的字符数组,我想将其转换为十进制格式,但是我收到错误:
incompatible types in assignment of 'int' to 'char [(((sizetype)(((ssizetype)size) + -1)) + 1)]'
这是我的代码:
const char input[] = "0d76";
int size = strlen(input);
char hex_array[size];
for(int i = 0; i < size; i++)
{
if ('0' <= input[i] && input[i] <= '9')
{
hex_array = input[i] - '0';
}
if ('a' <= input[i] && input[i] <= 'f')
{
hex_array = 10 + (input[i] - 'a');
}
if ('A' <= input[i] && input[i] <= 'F')
{
hex_array = 10 + (input[i] - 'A');
}
}
如果我输入 0D76 ,我会得到所需的输出。我会以十进制格式获得 3446 。
同样,如果有人有更好的方法将char数组从十六进制转换为十进制而不使用任何库函数,我将不胜感激。
答案 0 :(得分:1)
这里你的实现是错误的,并且在分配时也使用了char数组
将hex_array声明为整数数组
int hex_array[size];
if ('0' <= input[i] && input[i] <= '9')
{
hex_array[i] = input[i] - '0'; // this converts , Ascii digit to integer digit
//^^ make change here
}
if ('a' <= input[i] && input[i] <= 'f')
{
hex_array[i] = 10 + (input[i] - 'a'); // here this convers d==>13
}
if ('A' <= input[i] && input[i] <= 'F')
{
hex_array[i] = 10 + (input[i] - 'A'); //this convers D ==>13 and assigns to array
}
如果您提供输入
"0D76"
hex_array[0]=0,hex_array[1]=13, hex_array[2]=7,hex_array[4]=6.
现在您有十六进制字符的十进制值,
现在使用循环并将hex_array的每个值与它们的基数16的位置值相乘。
double decimal=0;
int i;
for(i = 0; i < size; i++)
decimal=decimal+hex_array[i]*pow(16,size-1-i);
十进制包含,十六进制十进制输入的十进制值。
答案 1 :(得分:1)
我不是......我非常相信许多其他答案的质量,我担心。
您的基本问题很简单:数组不是C中的可分配对象,您永远不能直接分配给数组。
然后,第二个问题就变成了如何将十六进制的字符串转换为十进制字符串。正常的,预期的和最好的方式当然是使用库函数,因为它已经被编写,调试,测试,并为其他程序员所熟知,这有助于使您的代码更容易理解。
如果你想走进图书馆作者的足迹,或者只是亲自动手并自己进行低级转换,那当然没问题。这是我将如何做到这一步,分两步:
strtoul()
]。snprintf()
]。代码:
unsigned long hex_to_ulong(const char *hex)
{
unsigned long x = 0;
while(isxdigit((unsigned int) *hex))
{
const unsigned int here = tolower((unsigned int) *hex++);
x *= 16;
if(isdigit(here))
x += here - '0';
else if(here == 'a') /* NOTE: Don't assume anything about the a-f encoding. */
x += 10;
else if(here == 'b')
x += 11;
else if(here == 'c')
x += 12;
else if(here == 'd')
x += 13;
else if(here == 'e')
x += 14;
else if(here == 'f')
x += 15;
}
return x;
}
第二部分的代码通常是这样的:
/* Create decimal string version of x in the given buffer, returning pointer to
* the first digit, which is *not* necessarily at out[0].
*/
char * ulong_to_dec(char *out, size_t out_max, unsigned long x)
{
char *put = out + out_max;
*--put = '\0';
do {
if(put == out)
return NULL;
*--put = '0' + (x % 10);
x /= 10;
} while(x != 0);
return put + 1;
}
然后你的问题基本上变成了:
const char input[] = "0d76";
const unsigned long x = hex_to_ulong(input);
char dec_array[10];
char *dec = ulong_to_dec(dec_array, sizeof dec_array, x);
puts(dec);
注意:上面的代码是未经测试的,有点繁琐,所以可能存在错误,但你明白了。
答案 2 :(得分:0)
这是一个过早优化的例子:
int h2i(int c){ /* use bit hacks to hex char -> int */
if ((unsigned)c-'0'<10) return(c-'0');
if (((unsigned)c|32)-'a'<6) return(((unsigned)c|32)-'a'+10);
return -1;
}
int s2i(char *s){
int i,ret=0;
while(*s=='0'||*s=='x')*s++; /* handle 0000ff... and 0xff... */
while(*s){
i=h2i(*s);
if (i==-1) return 0;
else ret=(ret<<4)|i;
}
return ret;
}
char *i2s(int n){
static char buf[(sizeof(int)<<1)+1]={0};
int i=0;
while(i<(sizeof(int)<<1)+1){ /* mask the ith hex, shift it to lsb */
// buf[i++]='0'+(0xf&(n>>((sizeof(int)<<3)-i<<2))); /* less optimizable ??? */
buf[i++]='0'+(0xf&((n&(0xf<<((sizeof(int)<<3)-i<<2)))>>((sizeof(int)<<3)-i<<2)));
if(buf[i-1]>'9')buf[i-1]+=('A'-'0'-10); /* handle A-F */
}
for(i=0;buf[i++]=='0';)
/*find first non-zero*/;
return (char *)buf+i;
}
#include <stdio.h>
int main(void){
printf("%s\n",i2s(0xf768cbaf));
return printf("%X\n",s2i("0xf768cbaf"));
}
答案 3 :(得分:0)
这可能在这里被问了一百万次,但这是一个简单的通用解决方案,通过int
,除了tolower()
之外没有使用库函数(你可以通过坚持大写或小写来避免)和strlen()
(很难完全避免,以及你在代码中使用的那些):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int st_to_int(char * st, int base);
void int_to_st(int n, char * buffer, int base);
void reverse_string(char * buffer);
int main(void) {
char input[] = "0D76";
int n = st_to_int("0D76", 16);
printf("Hex string '%s' converted to an int is %d.\n", input, n);
char buffer[100];
int_to_st(n, buffer, 10);
printf("%d converted to a decimal string is '%s'.\n", n, buffer);
int_to_st(n, buffer, 16);
printf("%d converted to a hex string is '%s'.\n", n, buffer);
return EXIT_SUCCESS;
}
int st_to_int(char * st, int base) {
static const char digits[] = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
'u', 'v', 'w', 'x', 'y', 'z'
};
int result = 0;
while ( *st ) {
result *= base;
for ( int i = 0; i < (int) sizeof(digits); ++i ) {
if ( digits[i] == tolower(*st) ) {
result += i;
break;
}
}
++st;
}
return result;
}
void int_to_st(int n, char * buffer, int base) {
static const char digits[] = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
'u', 'v', 'w', 'x', 'y', 'z'
};
int i = 0;
while ( n > 0 ) {
int next_digit = n % base;
n = n / base;
buffer[i++] = digits[next_digit];
}
buffer[i] = 0;
reverse_string(buffer);
}
void reverse_string(char * buffer) {
int buflen = strlen(buffer) + 1;
char revbuf[buflen];
int i;
for ( i = 0; i < buflen - 1; ++i ) {
revbuf[i] = buffer[buflen - 2 - i];
}
revbuf[i] = 0;
for ( i = 0; i < buflen; ++i ) {
buffer[i] = revbuf[i];
}
}
给出输出:
paul@local:~/src/c/scratch/strconv$ ./strconv
Hex string '0D76' converted to an int is 3446.
3446 converted to a decimal string is '3446'.
3446 converted to a hex string is 'd76'.
paul@local:~/src/c/scratch/strconv$
此代码不会检查缓冲区溢出或无效输入(例如非字母数字输入),作为练习留下。同样,它不处理负数或0.很容易修改,但你想避免'复杂/冗长'。