簡體   English   中英

如何在C中手動將十進制值轉換為十六進制字符串?

[英]How to manually convert decimal value to hexadecimal string in C?

我知道這個問題之前已經在各種不同的方式和情況下被問到了StackOverflow,但是我尋找的答案的搜索對我的具體案例並沒有多大幫助。 所以雖然這看起來像是一個問題的副本,例如如何將整數轉換為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)函數,我都是耳朵, void asciiToHexadecimal(char inputChar, char *hexString) ,我的調試似乎表明值是正常的,但輸出結果喜歡\\377而不是預期的十六進制字母數字表示。

對不起,如果問題本身(或代碼)有任何術語或其他問題,我仍然是C世界的新手。

更新:我剛剛想到,在打印時顯示值的方式可能是相關的,而不是故障的轉換。 這里是:

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所有內容都可以工作,但hexString除外)

 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之間的數字。

布道? 單元測試 ,如果你寫,你寫的代碼,同時測試可以為您節省數小時的時間。

有些人喜歡先寫測試。 雖然我從未有過遵守這種方法的紀律,但知道你必須編寫測試會迫使你編寫更容易測試的代碼。 而且更易於測試的代碼耦合較少 (或“更加分離”),這通常會導致更少的錯誤!

盡早和經常寫測試。 :)

更新 :包含輸出代碼后,我不得不對此發表評論:)

 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'字符留出空間。 如果您使用%c格式說明符打印hexString ,或者使用memcpy(3)構建更大的字符串,則可能沒問題,但是您的printf()調用將hexString視為字符串。

一般來說,當你看到一個

char *foo = malloc(N);

打電話,害怕 - C成語是

char *foo = malloc(N+1);

+1是你向其他人(以及你自己,在兩個月內)發出的信號,表明你為NUL留下了空間。 如果你在另一個計算中隱藏了那個+1 ,那么你就錯過了一個記憶模式的機會,這種模式可以在你每次閱讀代碼時捕獲這些錯誤。 (老實說,我在兩天前通過SO的確切模式找到了其中一個。:)

我做了一個librairy來進行十六進制/十進制轉換而不使用stdio.h 使用非常簡單:

char* dechex (int dec);

這將使用calloc()來返回指向十六進制字符串的指針,這樣就可以優化使用的內存量,所以不要忘記使用free()

這里是github上的鏈接: https//github.com/kevmuret/libhex/

目標是純十六進制,還是函數可以參數化。 如果它被限制為十六進制,為什么不利用這個事實,一個十六進制數字正好編碼四位?

我就是這樣做的:

#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;
}
#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;
    //
}

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

如果由這些十六進制或十進制字符串表示的數字很大(例如數百個數字),則它們將不適合long long整數(或C實現提供的任何最大整數類型)。 然后你需要bignums 我建議不要編寫自己的實現(制作一個有效的實現是很棘手的),但是使用像GMPlib這樣的現有實現

你非常接近 - 進行以下兩個小改動,它將足以讓你完成它:

(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; } 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM