最近在做一些C语言的笔试练习题,其中有一个题目如下:
输入的ASCII码字符串的前两字节分别是十六进制的前缀’0’和’x’,所以在处理时,要注意,接着再对十六进制前缀后面的部分进行转换,具体步骤分为如下几步:
① 计算ASCII码字符串的长度
② 分离出ASCII字符串中的十六进制前缀
③ 将ASCII字符串中的0-9的ASCII字符转换成十进制整数
④ 将ASCII字符串中的A-F或a-f转换成十进制整数
⑤ 以上转换过程中要注意十六进制数每个位的权重,如个位是160,十位是161
int asciiToHex(char* str) { size_t i = 0; //测量ASCII字符串的长度 size_t temp = 0; int base = 0; //基数权重 i = strlen(str); /*while (str[i]) { i++; }*/ //识别出字符串中的十六进制前缀 if ((str[0] == '0') && (str[1] == 'x')) { str += 2; i -= 2; } //按照***从右到左***的顺序进行转换 for (size_t j = 0; j < i; j++) { //计算每次循环分离数的权重 base = pow(16, (i - j - 1)); //分离出字符串中的 0-9 if (str[j] >= 48 && str[j] <= 57) { temp += base * (str[j] - '0'); } //分离出字符串中的 A-F else if (str[j] >= 65 && str[j] <= 90) { temp += base * (str[j] - 'A'+10); } //分离出字符串中的 a-f else if (str[j] >= 97 && str[j] <= 122) { temp += base * (str[j] - 'a' + 10); } //printf("j= %d ,temp=%ld\r\n", j, temp); } return temp; }
① 仅对符合size_t的整数进行转换(介绍思想)
② size_t的类型在本人电脑上定义为32位的unsigned int
③ 不管是十进制还是十六进制,在内存中都是以二进制存储,以此为切入点,当输入size_t的32位整数时, 先分离低四位,最后分离到高四位(刚好在十六进制的0-F范围内)。总共可以分离出8个数,并放入数组中。
④ 对③所述的整数数组按照顺序从高到低进行遍历,找出来第一个不为0的位置开始转换(防止转换出的结果为’0x0000001A’)。
char* hexToAscii(size_t hex,char *str_hex) { unsigned char temp[8]; unsigned char j = 2; //循环转换ASCII,前两位被十六进制前缀'0x'占用 char i = 0; //循环变量i必须定义为有符号型,否则会自减溢出 str_hex[0] = '0', str_hex[1] = 'x'; for (i = 0; i < 8; i++) { //循环依次分离 temp[i] = (hex >> (i * 4)) & 0xF; } for (i = 7; i >=0; i--) { if (temp[i]) { //找出第一个不为零的位置开始转换 while (i >= 0) { if (temp[i] < 10) { str_hex[j] = temp[i] + '0'; } else { str_hex[j] = temp[i] -10 + 'A'; } i--; j++; } str_hex[j] = NULL; //令转换后的ASCII字符串以空字符结尾 break; } } }
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> int main(void) { char *str = "0xabcd123"; int num = 0; char strHex[10]; //char strHex[10] = " "; size_t hexNum = 0x456AB; num = asciiToHex(str); printf("0x%x\r\n", num); hexToAscii(hexNum, strHex); printf("hexNum = 0x%x\r\n",hexNum); printf("hexToAscii: %s\r\n",strHex); return 0; }
以上只是本人的想法,操作的时候注意C语言中的字符串注意事项
PS:由“阿拉如爷”赞助,喜欢的点个赞~哈哈ψ(`∇´)ψ