查找不可打印的字符并在 C 中打印出它们的十六进制形式

Finding unprintable characters and printing out their hex form in C

我目前有一个有限状态机,它分析一个长字符串,用白色分隔长字符串 space,并将每个标记分析为八进制、十六进制、浮点数、错误等。

以下是我如何分析每个标记的简要概述:

enum state mystate = start_state; 

while (current_index <= end_index - 1) { // iterate through whole token
    switch (mystate) {
        case 0:
            // analyze first character and move to appropriate state
            // cases 1-5 represent the valid states, if error set mystate = 6
        case 6: // this is the error state
            current_index = end_index - 1; // end loop
            break; 
    }
    current_index++;
}

在此循环结束时,我分析了我的令牌所处的状态,例如令牌不属于任何类别并且它进入了状态 6(错误状态):

if (mystate == 6) {
    // token is char pointer to string token
    fprintf(stdout, "Error: \" %s \" is invalid\n", token);
}

现在,我应该以十六进制形式打印出 0x20 及以下的不可打印字符,例如 start-of-text、start-of-header 等,例如 [0x02] 和 [0x01] .我从 0x20 和下面找到了一份很好的 ASCII 不可打印字符列表:http://www.theasciicode.com.ar/ascii-control-characters/start-of-header-ascii-code-1.html

首先,我很困惑如何在命令行中输入不可打印的字符。如何键入不可打印的字符作为我的程序分析的命令行参数?

过了那个关卡,我知道不可打印的字符会落入状态 6,我的错误状态。所以我必须稍微修改我的错误状态 if 语句。这是我在伪代码中如何做到这一点的思考过程:

if (mystate == 6) {
    if (token is equal to unprintable character) {
        // print hex form, use 0x%x for formatting
    } else {
        // still error, but not unprintable so just have original error statement
        fprintf(stdout, "Error: \" %s \" is invalid\n", token); 
    }
}

我的另一个想法是:

if (mystate == 6) {
    if (the token's hex value is between 0x01 and 0x20) {
        // print hex form, use 0x%x for formatting
    } else {
        // still error, but not unprintable so just have original error statement
        fprintf(stdout, "Error: \" %s \" is invalid\n", token); 
    }
}

你的一块拼图正在以十六进制打印。

Printf("%02x", 7);

这将打印两位十六进制值 07。

另一件正在检测不可打印。

如果(c < 20)。

这意味着该字符的值小于 space。

您可能会研究 isprint 函数,因为有些字符大于 space。

祝你好运。欢迎来到c.

有了理智的 libc,你会使用

#include <ctype.h>
...
if (!isprint((int)ch) {
    unsigned x = ch;
    printf ("[0x%02x]", 0xff&(int)ch);
}
...

查找不可打印的 ascii 字符,假设 char ch 是您当前输入的字符。

要在命令行中使用它们,您可以从命令行使用 printf(1)。

printf '\x02'|xxd
0000000: 02

您看到了 STX 字符。顺便提一句。有一个关于 ascii (ascii(7)) 的优秀手册页!

所以作为一个完整的命令行:

YOUR_Program "`printf '\x02\x03\x18\x19'`"

(xxd 只是为了展示 printf 的结果,因为它是不可打印的)。 xxd 只是一个 hexdump 实用程序,类似于 od。

注意:当您确实需要不可打印的输入时,从文件或标准输入中获取输入会更方便。这简化了您的程序调用:

printf '\x02\x03\x18\x19'|YOUR_Program