平時我們在寫功能需求時,難免不會遇到需要將16
進制字符串轉換成字符串,或者字符串轉16進制字符串的需求,所以就有了這篇文章。
在進入主題之前,我們先來回顧一下字符和16
進制的關系。我們知道正常的16
進制數(shù)值(像0x32
)和ASIIC
碼(0x32
對應字符2
)之間是互通的,即如果你輸出數(shù)值,就是輸出的字符的數(shù)值(例如,字符0
,十進制就是48
),如果你輸出字符,那就是輸出的字符,不會進行轉換(例如,字符0
,輸出就是字符0
),具體可以看下面示例:
char ch = '0';
int i = 48;
printf("int: %d", ch); // 輸出: int: 48
printf("char: %c", ch); // 輸出: char: 0
printf("int: %d", i); // 輸出: int: 48
printf("char: %c", i); // 輸出: char: 0
16進制字符串轉字符串
言歸正傳,現(xiàn)在我們先來看看16
進制字符串轉字符串,大致的邏輯就是將16
進制字符串每兩個字符組合在一起得到一個16
進制的字符串,然后再打包轉成對應的字符。我們可以利用庫函數(shù)strtol()
,其函數(shù)聲明為long int strtol(const char *str, char **endptr, int base)
,該函數(shù)的功能是把參數(shù) str
所指向的字符串根據(jù)給定的 base
轉換為一個長整數(shù)(類型為 long int
型),base
必須介于 2
和 36
(包含)之間,或者是特殊值 0
。
- 參數(shù):
-
str
– 要轉換為長整數(shù)的字符串 -
endptr
– 對類型為char*
的對象的引用,其值由函數(shù)設置為str
中數(shù)值后的下一個字符 -
base
– 基數(shù),必須介于2
和36
(包含)之間,或者特殊值0
。如果base
為0
,則會根據(jù)字符串的前綴來判斷進制
-
- 返回值:
函數(shù)返回被轉換的長整型整數(shù)值。如果輸入字符串不符合數(shù)字格式,strtol()
將返回0
。如果轉換結果超出了long
整數(shù)的表示范圍,那么將產(chǎn)生溢出,并設置errno
為ERANGE
。你可以使用<errno.h>
頭文件中的errno
變量來檢查是否有溢出發(fā)生。
現(xiàn)在我們來進行實戰(zhàn)操作,如下示例:
#include <stdlib.h> // 要使用strtol()庫函數(shù),需要包含頭文件
char data[] = "48656C6C6F20576F726C6421210D0A"; // 假如,我們接收到這樣的數(shù)據(jù)
char res[32]; // 儲存轉換后的結果
int hex_str_2_str(char *dest, char *src)
{
int len = strlen(src); // 獲取接收數(shù)據(jù)長度
int i,j;
for (i = 0, j = 0; i < len; i+=2) { // 每次取兩個字符
char tmp_buf[3]; // 每兩個字符組成一個16進制字符串,同時結尾需要空字符來告訴編譯器我們的是字符串
char *endptr; // 保存已轉換數(shù)值后的下一個字符
// 以下為取待轉換的16進制字符串
tmp_buf[0] = src[i];
tmp_buf[1] = src[i + 1];
tmp_buf[2] = '\0'; // 記得添加空字符
// 轉換成16進制,base傳16即可
dest[j++] = strtol(tmp_buf, &endptr, 16);
}
dest[j] = '\0'; // 添加字符串結束符
return j;
}
int len = hex_str_2_str(res, data);
printf("len: %d, str: %s", len, res); // len: 15, str: Hello World!!
字符串轉16進制字符串
前面介紹了16
進制字符串轉字符串,那現(xiàn)在我們來試試如何反過來轉換。具體操作是依次將每個字符拿到并轉換成對應的16
進制,然后再以字符串的形式儲存在容器中即可。
在這里我們需要用到庫函數(shù)sprintf()
,其函數(shù)聲明為int sprintf(char *str, const char *format, ...)
,該函數(shù)是把格式化輸出內容發(fā)送到所指向的字符串str
中。
-
參數(shù):
-
str
– 指向一個字符數(shù)組的指針,該數(shù)組存儲了C
字符串 -
format
– 這是字符串,包含了要被寫入到字符串str
的文本。它可以包含嵌入的format
標簽,format
標簽可被隨后的附加參數(shù)中指定的值替換,并按需求進行格式化
-
-
返回值:
如果成功,則返回寫入的字符總數(shù),不包括字符串追加在字符串末尾的空字符。如果失敗,則返回一個負數(shù)。
具體操作如下示例:
#include "stdio.h" // sprintf()函數(shù)聲明所在的頭文件
char data[] = "Hello World!!\r\n";
char res[32];
int str_2_hex_str(char *dest, char *src)
{
int len = strlen(src); // 獲取接收數(shù)據(jù)長度
int i,j;
for (i = 0, j = 0; i < len; i++) {
// %02X: 是格式化字符串,意思是以大寫的形式(通過X大小寫控制)轉換成16進制,長度不足2的自動補0
sprintf(&dest[j], "%02X", src[i]);
j+=2; // 每個16進制占2個長度
}
dest[j] = '\0'; // 添加字符串結束符
return j; // 返回字符串長度
}
int len = str_2_hex_str(res, data);
printf("len: %d, hex: %s", len, res); // len: 30, hex: 48656C6C6F20576F726C6421210D0A
總結
要想實現(xiàn)16
進制字符串和字符串之間的相互轉換,只要用好strtol()
和sprintf()
這兩個庫函數(shù),就可以輕松解決
參考
https://www.runoob.com/cprogramming/c-function-strtol.html
https://www.runoob.com/cprogramming/c-function-sprintf.html文章來源:http://www.zghlxwxcb.cn/news/detail-782120.html
關注公眾號《嵌入式從入門到放棄》了解更多知識文章來源地址http://www.zghlxwxcb.cn/news/detail-782120.html
到了這里,關于【C語言小技巧】16進制字符串與字符串互轉的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!