C 解析具有名称、十六进制值等的字符串的最佳方法是什么。?

C 解析具有名称、十六进制值等的字符串的最佳方法是什么。?,c,parsing,C,Parsing,基本上,我有一个文件,其中包含我必须解析的多行。例如,我可能有这样的形式:“荷马·辛普森吃了@0x000000000000牛肉甜甜圈” 恢复名字很简单,就是恢复他吃的甜甜圈的数量,我有麻烦。换句话说,我想将这个数字存储在uint64_t变量中 我的第一种方法是简单地从一个字符到另一个字符读取数字并将其转换为十进制(即,我将计算0*16^15+0*16^14+…+e*16^1+F*16^0)。这种方法对我来说似乎非常昂贵,我相信一定有更好的方法来实现这一点。然而,这种技术的优点是,如果数字是这样写

基本上,我有一个文件,其中包含我必须解析的多行。例如,我可能有这样的形式:“荷马·辛普森吃了@0x000000000000牛肉甜甜圈”

恢复名字很简单,就是恢复他吃的甜甜圈的数量,我有麻烦。换句话说,我想将这个数字存储在uint64_t变量中

我的第一种方法是简单地从一个字符到另一个字符读取数字并将其转换为十进制(即,我将计算0*16^15+0*16^14+…+e*16^1+F*16^0)。这种方法对我来说似乎非常昂贵,我相信一定有更好的方法来实现这一点。然而,这种技术的优点是,如果数字是这样写的“@0x0000 0000 BEEF”,我仍然能够将其转换为uint64_t变量

我尝试的第二种方法是使用sscanf或strol(如许多其他帖子所述,比如这篇:)。这个方法的问题是,我首先必须从原始字符串创建一个子字符串“@0x000000000000BEEF”(strol也是如此)。同样,这种技术是有效的,但如果我有“@0x0000牛肉”,它就不起作用了

对于我来说,有没有一种聪明而简单的方法来恢复这个数字并将其存储在uint64\t变量中

这个问题与其他帖子中的问题不同。他们所要做的就是将十六进制字符串转换为uint64_t。我的问题不同

我有一个字符串,它不是简单地由十六进制值组成的,十六进制值的格式可能会随着行的变化而变化,并且可能有空格分隔的单词。例如,我可能有:

"Bart annoyed @00000000000000AA people today"
或者十六进制值可以这样写:

"Bart annoyed @0000 0000 0000 00AA people today"

如何从十六进制数中读取每一行,然后将其转换为字符串,如其他答案所示?

扫描集可与
sscanf
一起使用,以捕获到@的行部分。
然后扫描
@0x
并使用
%n
获取已处理的字符数,以用作进一步处理的索引。
使用
%1x%n
扫描每个十六进制数字并计算处理的字符数。这将在跳行空格中进行迭代。将扫描的字符数添加到
索引中,并使用
输入+索引进行迭代
将每个十六进制数字合并到十六进制值中。这会移动该值,并将数字移动到

#include <stdio.h>
#include <inttypes.h>

#define SIZE 100
//so SIZE can be part of sscanf Format String
#define SSFS(x) #x
#define FS(x) SSFS(x)


int main( void) {
    char input[SIZE + 1] = "Homer Simpson ate @0x0000 0000 0000 B E E F donuts";
    char name[SIZE + 1] = "";
    int index = 0;
    int scanned = 0;
    int digit = 0;
    uint64_t hex = 0;
    unsigned int hexdigit = 0;

    sscanf ( input, "%"FS(SIZE)"[^@]@0x%n", name, &index);
    if ( index) {
        while ( digit < 16 && 1 == sscanf ( input + index, "%1x%n", &hexdigit, &scanned)) {
            digit++;
            index += scanned;
            hex <<= 4;
            hex |= hexdigit;
        }
        printf ( "name [%s] [%" PRIu64 "] [%s]\n", name, hex, input + index);
    }

    return 0;
}
#包括
#包括
#定义大小100
//因此,大小可以是sscanf格式字符串的一部分
#定义SSF(x)#x
#定义FS(x)SSFS(x)
内部主(空){
字符输入[SIZE+1]=“霍默·辛普森ate@0x0000 B E E F甜甜圈”;
字符名称[大小+1]=“”;
int指数=0;
int=0;
整数位数=0;
uint64_t十六进制=0;
无符号整数十六进制数=0;
sscanf(输入,“%”FS(大小)“[^@]@0x%n”、名称和索引);
如果(索引){
而(数字<16&&1==sscanf(输入+索引,%1x%n“,&hexdigit,&scanned)){
数字++;
索引+=扫描;

十六进制看起来似乎不正确,但问题也很模糊。您希望在这里匹配什么…关于“荷马·辛普森吃了@0x000000000000牛胸肉”如何?匹配到底是什么意思?基本上,我有一个十六进制值,由十六个字符组成(在您的示例中是“@0x000000000000000000牛胸肉”)我想把它转换成一个uint64_t变量。现在每一行都可以不同,因为我可以有一行“Marge在杂货上花费了@0xaaaa0000”“用C进行解析没有什么是容易的。那你有什么想法吗?我甚至不会使用
sscanf
,只是一个带有
fgetc
的状态机,然后将所有
isxdigit
读到一个17+的缓冲区中,当缓冲区满时,就可以使用
strtoull
,但这算不上是“容易”了,非常感谢你。”