两个Char数组之间分配中的不兼容类型

时间:2013-10-04 02:55:43

标签: c arrays

我有一个十六进制格式为“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 个答案:

答案 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中的可分配对象,您永远不能直接分配给数组。

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

如果你想走进图书馆作者的足迹,或者只是亲自动手并自己进行低级转换,那当然没问题。这是我将如何做到这一步,分两步:

  1. 将十六进制字符串转换为库中的(二进制)整数[strtoul()]。
  2. 将整数转换为十进制字符串[library:snprintf()]。
  3. 代码:

    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.很容易修改,但你想避免'复杂/冗长'。