查找不可打印的字符并在C

时间:2015-07-02 14:34:31

标签: c string state-machine

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

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

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及以下打印出不可打印的字符,例如文本开头,标题开头等,以十六进制形式,如[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); 
    }
}

2 个答案:

答案 0 :(得分:2)

使用理智的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角色。 BTW。有一个关于ascii(ascii(7))的优秀手册页!

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

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

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

注意:当你真的想要不可打印的输入时,从文件或stdin获取输入会更方便。这简化了您的程序调用:

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

答案 1 :(得分:-2)

你的谜题的一部分是以十六进制打印。

Printf("%02x", 7);

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

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

如果(c <20)。

这会转换为字符的任何值小于空格。

您可能会研究isprint函数,因为有一些不可打印的字符大于空格。

祝你好运。欢迎来到c。