如何在C中手动将十进制值转换为十六进制字符串?

时间:2011-03-08 10:57:15

标签: c hex decimal

n.b。我知道StackOverflow之前已经以各种不同的方式和情况询问了这个问题,但是我寻找的答案并没有对我的具体情况有所帮助。因此,虽然这最初看起来像How can I convert an integer to a hexadecimal string in C?这样的问题的副本,所给出的答案是准确的,但对我没用。

我的问题是如何手动将十进制整数转换为十六进制字符串。我知道stdlib.h和printf有一些节拍技巧,但这是一项大学任务,我需要手动完成(教授的命令)。但是,我们可以寻求帮助。

使用好的旧“除以16并将余数转换为十六进制并反转值获取十六进制字符串的方法,但我的代码中必定存在一个大错误,因为它不是让我回来,例如“BC”为十进制值“188”。

假设算法永远不需要为大于256(或FF)的小数找到十六进制值。虽然参数的传递可能不是最佳或可取的,但我们已经被告知要使用它(虽然我可以修改getHexValue函数,因为我自己编写了这个函数)。

这是我到目前为止所做的:

/* Function to get the hex character for a decimal (value) between
 * 0 and 16.  Invalid values are returned as -1.
 */
char getHexValue(int value) 
{
   if (value < 0) return -1;
   if (value > 16) return -1;
   if (value <= 9) return (char)value;
   value -= 10;
   return (char)('A' + value);
}


/* Function asciiToHexadecimal() converts a given character (inputChar) to
 * its hexadecimal (base 16) equivalent, stored as a string of
 * hexadecimal digits in hexString. This function will be used in menu
 * option 1.
 */
void asciiToHexadecimal(char inputChar, char *hexString)
{
   int i = 0;
   int remainders[2];
   int result = (int)inputChar;
   while (result) {
      remainders[i++] = result % 16;
      result /= (int)16;
   }
   int j = 0;
   for (i = 2; i >= 0; --i) {
      char c = getHexValue(remainders[i]);
      *(hexString + (j++)) = c;
   }
}

char *hexString是指向我需要输出到屏幕(最终)的字符串的指针。我需要转换为十六进制的char inputChar参数(这就是我永远不需要将值转换为256的原因)。

如果还有更好的方法,仍然使用void asciiToHexadecimal(char inputChar, char *hexString)函数,我很满意,除此之外,我的调试似乎表明值正常,但输出结果如{ {1}}而不是预期的十六进制字母数字表示。

很抱歉,如果问题本身(或代码)有任何术语或其他问题,我对C世界仍然很陌生。

更新 我刚想到,在打印时显示值的方式可能是相关的,而不是故障的转换。这是:

\377

(此代码片段中的所有内容均可用于char* binaryString = (char*) malloc(8); char* hexString = (char*) malloc(2); asciiToBinary(*(asciiString + i), binaryString); asciiToHexadecimal(*(asciiString + i), hexString); printf("%6c%13s%9s\n", *(asciiString + i), binaryString, hexString);

6 个答案:

答案 0 :(得分:2)

char getHexValue(int value)
{
   if (value < 0) return -1;
   if (value > 16) return -1;
   if (value <= 9) return (char)value;
   value -= 10;
   return (char)('A' + value);
}

您可能希望打印出针对您感兴趣的每个值调用此例程所获得的字符。:)(printf(3) format %c。)

当您使用0到9之间的数字呼叫getHexValue()时,您将在ASCII控制字符范围内返回0到9之间的数字。当您使用10到15之间的数字呼叫getHexValue()时,您将在ASCII字母范围内返回65到75之间的数字。

布道?如果您在编写代码的同时编写测试,Unit testing可以节省小时

有些人喜欢先写测试。虽然我从来没有遵守这种方法很长时间,但是知道你来编写测试会迫使你编写更容易来测试的代码。更容易测试的代码是less coupled(或“更多解耦”),这通常会导致更少的错误!

尽早并经常写测试。 :)

更新:在您输入输出代码后,我不得不对此发表评论:)

char* binaryString = (char*) malloc(8);
char* hexString = (char*) malloc(2);
asciiToBinary(*(asciiString + i), binaryString);
asciiToHexadecimal(*(asciiString + i), hexString);
printf("%6c%13s%9s\n", *(asciiString + i), binaryString, hexString);

hexString已分配一个字节太小而不能成为C字符串 - 您忘记为ASCII NUL '\0'字符留出空间。如果您使用hexString格式说明符打印%c,或使用memcpy(3)构建更大的字符串,则可能没问题,但您的printf()调用正在处理{{1}作为一个字符串。

一般来说,当你看到

hexString
打电话,害怕 - C成语是

char *foo = malloc(N);

char *foo = malloc(N+1); 是你向其他人(以及你自己,在两个月内)发出的信号,表明你为NUL留下了空间。如果你在另一个计算中隐藏+1,那么你就错过了记忆每次读代码时都能捕获这些错误的模式的机会。 (老实说,我在两天前通过SO的确切模式找到了其中一个。)

答案 1 :(得分:1)

目标是纯十六进制,还是函数可以参数化。如果它被限制为十六进制,为什么不利用这个事实,一个十六进制数字正好编码四位?

我就是这样做的:

#include <stdlib.h>

#include <limits.h> /* implementation's CHAR_BIT */

#define INT_HEXSTRING_LENGTH (sizeof(int)*CHAR_BIT/4)
/* We define this helper array in case we run on an architecture
   with some crude, discontinous charset -- THEY EXIST! */
static char const HEXDIGITS[0x10] = 
    {'0', '1', '2', '3', '4', '5', '6', '7',
     '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
void int_to_hexstring(int value, char result[INT_HEXSTRING_LENGTH+1])
{
    int i;
    result[INT_HEXSTRING_LENGTH] = '\0';

    for(i=INT_HEXSTRING_LENGTH-1; value; i--, value >>= 4) {
        int d  = value & 0xf;
        result[i] = HEXDIGITS[d];
    }

    for(;i>=0;i--){ result[i] = '0'; }
}
int main(int argc, char *argv[])
{
    char buf[INT_HEXSTRING_LENGTH+1];

    if(argc < 2)
        return -1;

    int_to_hexstring(atoi(argv[1]), buf);
    puts(buf);
    putchar('\n');

    return 0;
}

答案 2 :(得分:1)

我创建了一个librairy来进行十六进制/十进制转换而不使用stdio.h。使用非常简单:

char* dechex (int dec);

这将使用calloc()返回指向十六进制字符串的指针,这样就可以优化使用的内存量,所以不要忘记使用free()

这里是github上的链接:https://github.com/kevmuret/libhex/

答案 3 :(得分:0)

你非常接近 - 进行以下两项小改动,它将足以让你完成它:

(1)改变:

if (value <= 9) return (char)value;

为:

if (value <= 9) return '0' + value;

(你需要将转换 0..9的值转换为char,而不仅仅是转换它。)

(2)改变:

void asciiToHexadecimal(char inputChar, char *hexString)

为:

void asciiToHexadecimal(unsigned char inputChar, char *hexString)

(inputChar被视为已签名,因%}而产生了不良后果。

一些提示:

  • getHexValue返回'?'而非-1表示无效输入(使调试更容易)

  • 编写测试工具进行调试,例如

    int main(void)
    {
        char hexString[256];
    
        asciiToHexadecimal(166, hexString);
    
        printf("hexString = %s = %#x %#x %#x ...\n", hexString, hexString[0], hexString[1], hexString[2]);
    
        return 0;
    }
    

答案 4 :(得分:0)

#include<stdio.h>

char* inttohex(int);
main()
{
    int i;
    char *c;
    printf("Enter the no.\n");
    scanf("%d",&i);
    c=inttohex(i);
    printf("c=%s",c);
}

char* inttohex(int i)
{
    int l1,l2,j=0,n;
    static char a[100],t;

    while(i!=0)
    {
    l1=i%16;
    if(l1>10)
    {
        a[j]=l1-10+'A';
    }

    else
        sprintf(a+j,"%d",l1);

    i=i/16;
    j++;
    }
    n=strlen(a);
    for(i=0;i<n/2;i++)
    {
        t=a[i];
        a[i]=a[n-i-1];
        a[n-i-1]=t;
    }

    //printf("string:%s",a);
    return a;
    //
}

答案 5 :(得分:0)

补充其他好的答案......

如果这些十六进制或十进制字符串表示的数字很大(例如数百个数字),则它们不适合long long(或C实现提供的任何最大整数类型)。然后你需要bignums。我建议不要编写自己的实现(制作一个有效的实现很棘手),但使用现有的实现,如GMPlib