1

我有一个十六进制格式“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 数组从十六进制转换为十进制而不使用任何库函数,我将不胜感激。

4

4 回答 4

1

恐怕我对这个问题的许多其他答案的质量非常确信。

您的基本问题很简单:数组不是 C 中的可分配对象,您永远不能直接分配给数组。

然后第二个问题变成了如何将十六进制字符串转换为十进制字符串。正常的、预期的和最好的方法当然是使用库函数,因为它已经被编写、调试、测试过,并且为其他程序员所熟知,这有助于使您的代码更易于理解。

如果你想走图书馆作者的足迹,或者干脆自己动手做低级转换,那当然没问题。以下是我的做法,分两步:

  1. 将十六进制字符串转换为(二进制)整数[strtoul()在库中]。
  2. 将整数转换为十进制字符串 [library: 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);

注意:上面的代码未经测试,而且有些繁琐,因此可能存在错误,但您明白了。

于 2013-10-04T07:12:27.177 回答
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);

十进制包括,十六进制输入的十进制值。

于 2013-10-04T03:03:05.990 回答
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。很容易修改,但您想避免“复杂/冗长”。

于 2013-10-04T03:55:09.800 回答
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"));
}
于 2013-10-04T03:25:09.393 回答