代码之家  ›  专栏  ›  技术社区  ›  trueCamelType

如何从文件或输入中除去十六进制以外的所有内容?

  •  0
  • trueCamelType  · 技术社区  · 7 年前

    我试图读取一个包含随机语句、数据和十六进制块的文件。我只想读十六进制的。下面是该文件的一个简短示例。


    小样本文件

    Serial Number   :   1234
    More Data       :   7-9-2
    
    -------------------------
    
    Mak:  A5 12 00 24 00 01 22 00 4F 11
          A2 48 4A D1 53 6D 8A D1 61 40
    
    t+00:00:00:00   : Mix one
    
    Mak:  A5 22 30 44 50 01 22 00 4F 11
          A2 18 2A 31 43 6D 8A D1 61 40 
    
    A random sentence.
    

    下面是我用来读取文件中所有行的内容,并经常添加 strstr() 方法匹配我正在查找的特定十六进制值。如果我能去掉所有不是十六进制块格式的内容,或者只读取十六进制,那么匹配十六进制的整个过程就会简单得多。

    void ReturnAllLines(char *filePath)
    {
        char currentLine[100];
        FILE *file = fopen(filePath, "r");
    
        while(fgets(currentLine, sizeof(currentLine), file) != NULL)
        {
            printf(currentLine);
        }
    }
    

    在其他语言中,我使用regex或内置方法做过类似的事情,但我对c还不熟悉,我不确定最好的方法是什么。

    理想情况下,最终输出将类似于以下内容:

    A5 12 00 24 00 01 22 00 4F 11 A2 48 4A D1 53 6D 8A D1 61 40

    A5 22 30 44 50 01 22 00 4F 11 A2 18 2A 31 43 6D 8A D1 61 40

    每一个街区都有区别于两者的东西。但即使是一行巨大的十六进制也会工作得更好。我已经研究过使用 sscanf() ,但我尝试过的一切都失败了,我放弃了尝试,因为我不确定它是否能够做到这一点。

    1 回复  |  直到 7 年前
        1
  •  2
  •   David Collins    7 年前

    我想下面的话会让你很接近。它使用 strtok() 将每一行拆分为空格分隔的标记-然后使用 scanf() 检查标记是否为十六进制字符。

    你可以把它插到你的 ReturnAllLines() 功能(通过替换 printf(currentLine) 具有 PrintLineHex(currentLine) )

    void PrintLineHex(char *line) {
        char *nl = NULL, *tok = NULL;
        int convs = 0;
        unsigned ch = '\0';
        int hex_line = 0;
    
        nl = strchr(line, '\n');
        if (nl) *nl = '\0';  // Remove new-line char ...
        tok = strtok(line, " ");
        hex_line = 0;
        while (tok) {
            convs = sscanf(tok, "%x", &ch);
            if (convs == 1 && strlen(tok) == 2) {
                hex_line = 1;
                printf("%02hhX ", ch);
            }
            tok = strtok(NULL, " ");
        }
        if (hex_line) puts("");
    }
    

    它还检查每个令牌的宽度。如果你想适应不同字符宽度的十六进制值,你可以很容易地调整这个方面。

    使用示例输入输出…

    A5 12 00 24 00 01 22 00 4F 11   
    A2 48 4A D1 53 6D 8A D1 61 40   
    A5 22 30 44 50 01 22 00 4F 11   
    A2 18 2A 31 43 6D 8A D1 61 40