如何从文件或输入中去除除十六进制以外的所有内容?
How can I strip all but hex from file or input?
我正在尝试读取一个混合了随机句子、数据和十六进制块的文件。我只想读十六进制块。下面是该文件的一个简短示例。
小样本文件
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);
}
}
在其他语言中,我使用正则表达式或内置方法完成了类似的事情,但我是 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()
,但我尝试的一切都失败了,我放弃了尝试,因为我不确定它是否能够做到这一点。
我认为以下内容让您非常接近。它使用 strtok()
将每一行拆分为 space 分隔的标记 - 然后使用 scanf()
检查标记是否为十六进制字符。
您可以将其放入 ReturnAllLines()
函数中(通过将 printf(currentLine)
替换为 PrintLineHex(currentLine)
)。
void PrintLineHex(char *line) {
char *nl = NULL, *tok = NULL;
int convs = 0;
unsigned ch = '[=10=]';
int hex_line = 0;
nl = strchr(line, '\n');
if (nl) *nl = '[=10=]'; // 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
我正在尝试读取一个混合了随机句子、数据和十六进制块的文件。我只想读十六进制块。下面是该文件的一个简短示例。
小样本文件
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);
}
}
在其他语言中,我使用正则表达式或内置方法完成了类似的事情,但我是 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()
,但我尝试的一切都失败了,我放弃了尝试,因为我不确定它是否能够做到这一点。
我认为以下内容让您非常接近。它使用 strtok()
将每一行拆分为 space 分隔的标记 - 然后使用 scanf()
检查标记是否为十六进制字符。
您可以将其放入 ReturnAllLines()
函数中(通过将 printf(currentLine)
替换为 PrintLineHex(currentLine)
)。
void PrintLineHex(char *line) {
char *nl = NULL, *tok = NULL;
int convs = 0;
unsigned ch = '[=10=]';
int hex_line = 0;
nl = strchr(line, '\n');
if (nl) *nl = '[=10=]'; // 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