如何将不可打印的字符转换为 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);
}

https://godbolt.org/z/6jKWdr3rM