C语言中如何将不可打印字符转换为对应的十六进制值
异常输出的根因
- 符号扩展问题:绝大多数C编译器默认
char为有符号类型,当字符值大于127(0x7F)时会被识别为负数,传入printf可变参数时会触发整数提升,符号位扩展为4字节int,最终打印时就会出现ffffff前缀的冗余内容。你输出的ffffffc3、ffffff9f就是这个原因导致的。 - 编码不匹配问题:你示例中的
ß在扩展ASCII(ISO-8859-1/Latin-1编码)中是单字节值225(0xE1),但你当前输入的字符串是UTF-8编码,ß的UTF-8编码为双字节0xC3 0x9F,所以会输出两个转义序列,而非预期的E1。 - 代码逻辑错误:你使用
str[i] != NULL判断字符串结束是错误用法,NULL是指针常量,字符串结束符为字符'\0';同时isprint传入负数会触发未定义行为,该函数要求入参必须是unsigned char强转后的int值或EOF。 - 格式符问题:你使用
%02x会输出小写十六进制,要输出大写的E1需要使用%02X格式符。
正确实现方案
基础逻辑修正
以下代码解决了符号扩展、判断条件错误的问题,适配扩展ASCII编码的输入:
#include <stdio.h> #include <ctype.h> void myfunction(char *str) { if (str == NULL) return; for (int i = 0; str[i] != '\0'; i++) { // 强转为unsigned char消除符号问题 unsigned char cur = (unsigned char)str[i]; if (isprint(cur)) { printf("%c", cur); } else { // 取低8位输出大写两位十六进制 printf("%02X", cur); } } }
编码适配
如果你的输入为UTF-8编码,需要先将UTF-8字符串转码为ISO-8859-1编码后再送入函数处理,才能得到ß对应输出E1的效果;Windows平台也可通过设置控制台代码页为1252(西欧扩展ASCII)保证输入编码符合预期。
内容的提问来源于stack exchange,提问作者Issaminu
相关产品推荐
相关产品推荐

