如何将不可打印的字符转换为 C 中的十六进制值?
How to turn non-printable characters into their hex values in C?
我正在尝试制作一个函数,该函数将字符数组作为输入,并正常输出可打印字符和十六进制不可打印字符(通过使用扩展 ASCII 将这些字符转换为十进制,然后将其转换为十进制数转换为十六进制数)。
例如:
"This morning is ßright"
应该变成:
"This morning is E1right"
因为 ß 在扩展 ASCII 中是 225,而在十六进制中是 E1。
这是我的尝试:
void myfunction(char *str)
{
int size=0;
for (int i = 0; str[i] != NULL; i++) size++; //to identify how many characters are in the string
for (int i = 0; i < size; i++)
{
if (isprint(str[i]))
{
printf("%c", str[i]); //printing printable characters
}
else
{
if (str[i] == NULL) break; //to stop when reaching the end of the string
printf("%02x", str[i]); //This is where I'm having an issue
}
}
}
这个函数输出这个:
"This morning is ffffffc3ffffff9fright"
如何将不可打印的字符转换为它们的十六进制值?是什么导致此函数以这种方式运行?
提前致谢!
您在这里看到了几个问题。第一个是你机器上的 char
类型(和大多数机器一样)是有符号的,所以当你有一个不是 ascii 的字符时,它显示为负数。在将其打印为无符号的十六进制值之前,此符号会扩展到您的 int 大小,因此您会得到您看到的那些 ffffff 字符串。
如果将其屏蔽为 8 位,您会更清楚地看到十六进制值。使用
printf("%02X", str[i] & 0xff); // X to use upper-case hex chars for clarity
你会得到输出
This morning is C39Fright
现在您看到了第二个问题,即 ß 不是 ascii 字符。然而,它是 unicode 字符 #00DF,当它以 UTF-8 编码时,它显示为两字节序列 C3 9F。
你的代码有很多问题。
for (int i = 0; str[i] != NULL; i++) size++;
NULL
是指针str[i]
是char
。您只是想与 zero
进行比较,后者是一个 空字符 。 空字符与NULL指针不一样!!!
这里也一样:if (str[i] == NULL) break;
printf("%02x", str[i]);
您使用错误的格式将 char
值打印为数字。您应该使用 hh
大小修饰符。在附加代码中查看它是如何工作的。
使用正确的索引或大小类型 - size_t
而不是 int
您的代码过于复杂。
void myfunction(const char *str)
{
while(*str)
{
if (isprint(*str))
{
printf("%c", *str); //printing printable characters
}
else
{
printf("%02hhX", *str); //This is where I'm having an issue
}
str++;
}
}
int main(void)
{
char *str = "This morning is \xE1right";
myfunction(str);
}
我正在尝试制作一个函数,该函数将字符数组作为输入,并正常输出可打印字符和十六进制不可打印字符(通过使用扩展 ASCII 将这些字符转换为十进制,然后将其转换为十进制数转换为十六进制数)。 例如:
"This morning is ßright"
应该变成:
"This morning is E1right"
因为 ß 在扩展 ASCII 中是 225,而在十六进制中是 E1。
这是我的尝试:
void myfunction(char *str)
{
int size=0;
for (int i = 0; str[i] != NULL; i++) size++; //to identify how many characters are in the string
for (int i = 0; i < size; i++)
{
if (isprint(str[i]))
{
printf("%c", str[i]); //printing printable characters
}
else
{
if (str[i] == NULL) break; //to stop when reaching the end of the string
printf("%02x", str[i]); //This is where I'm having an issue
}
}
}
这个函数输出这个:
"This morning is ffffffc3ffffff9fright"
如何将不可打印的字符转换为它们的十六进制值?是什么导致此函数以这种方式运行?
提前致谢!
您在这里看到了几个问题。第一个是你机器上的 char
类型(和大多数机器一样)是有符号的,所以当你有一个不是 ascii 的字符时,它显示为负数。在将其打印为无符号的十六进制值之前,此符号会扩展到您的 int 大小,因此您会得到您看到的那些 ffffff 字符串。
如果将其屏蔽为 8 位,您会更清楚地看到十六进制值。使用
printf("%02X", str[i] & 0xff); // X to use upper-case hex chars for clarity
你会得到输出
This morning is C39Fright
现在您看到了第二个问题,即 ß 不是 ascii 字符。然而,它是 unicode 字符 #00DF,当它以 UTF-8 编码时,它显示为两字节序列 C3 9F。
你的代码有很多问题。
for (int i = 0; str[i] != NULL; i++) size++;
NULL
是指针str[i]
是char
。您只是想与 zero
进行比较,后者是一个 空字符 。 空字符与NULL指针不一样!!!
这里也一样:if (str[i] == NULL) break;
printf("%02x", str[i]);
您使用错误的格式将 char
值打印为数字。您应该使用 hh
大小修饰符。在附加代码中查看它是如何工作的。
使用正确的索引或大小类型 - size_t
而不是 int
您的代码过于复杂。
void myfunction(const char *str)
{
while(*str)
{
if (isprint(*str))
{
printf("%c", *str); //printing printable characters
}
else
{
printf("%02hhX", *str); //This is where I'm having an issue
}
str++;
}
}
int main(void)
{
char *str = "This morning is \xE1right";
myfunction(str);
}