3

我正在读取一个二进制文件,其中一个字节定义了一种数据类型。

通常:

0x13 => FOO
0x14 => BAR

但是,实际上,可以有多个相同类型的定义,然后在其他地方定义真正的类型,但它并不总是可访问的。因此,如果没有定义子规范,我想打印所有可能性。

例如:

0x13 => FOO
0x14 => BAR
0x14 => BAZ <-- also "type" 0x14
0x15 => XEN

为了存储类型定义和描述,我有一个格式为:

struct data_def {
    char id;
    char *name;
    char *desc;
    ...
};

如果可能的话,我会有一个数组,如下所示:

static const struct data_def data_db[][] = {

    ...
    } /* index 0x13 */
        {0x13, "FOO", "This is foo", ...}
    }, /* index 0x14 */
        {0x14, "BAR", "This is bar", ...},
        {0x14, "BAZ", "This is baz", ...}
    }, /* index 0x15 */
        {0x15, "XEN", "This is xen", ...}
    }
}

为了这样data_db[0x14][1].name == BAZ,等等。

但是AFAIK这是不可能的。或者是吗?(C89)。


我正在寻找另一种方法来做到这一点。正在考虑这样的事情:

static const struct data_def data_db[] = {
    ...
    {0x13, "FOO", "This is foo", ...},
    {0x14, "BAR", "This is bar", ...},
    {0x14, "BAZ", "This is baz", ...},
    {0x15, "XEN", "This is xen", ...}
}

然后有一个查找表,就像每个第一个条目开始的位置一样。当然,这也可以通过 looping 动态创建data_db,但宁愿静态定义它(我认为 - 我还没有决定):

static const char data_index[] {
    ...
    0x20, /* at index 0x13 of data_index */
    0x21, /* at index 0x14 of data_index */
    0x23, /* at index 0x15 of data_index */
}

通过执行以下操作,可以打印(或其他):

while (data_db[data_index[0x14 + i]].id == 0x14) {
         print data_db[data_index[0x14 + i]].name
         ++i
}

有没有更好的方法来解决这个问题?我想这是以前在类似情况下已经做过十亿次的事情。我宁愿不使用标准库之外的任何库,因为这最终只是程序的一小部分,其余代码也是“免费的”。

4

1 回答 1

1

这只是在黑暗中拍摄,但如果标识符组中的类型数量有上限,并且如果您可以使用您知道不会是您的类型之一的值,您可以执行以下操作:

#define MAX_NUM_TYPES    3
#define INVALID_TYPE     0xff

struct Data_Def{
    unsigned char id;
    char * name;
    char * desc;
};

static const struct Data_Def data_db[][MAX_NUM_TYPES] = {
 .
 .
 .

    {    /* Index 0x13  */
         /*  id           name      desc            */
        {    0x13,        "FOO",    "This is foo"    },
        {    0x13,        "BAR",    "This is bar"    },
        {    INVALID_TYPE, NULL,    NULL             },
    },
    {    /* Index 0x14  */
         /*  id           name      desc            */
        {    0x14,        "BAZ",    "This is baz"    },
        {    INVALID_TYPE, NULL,    NULL             },
        {    INVALID_TYPE, NULL,    NULL             },
    },
};

如果你想打印...

unsigned char index = 0;
/* Print all types within a group with id 0x13. */
while ((data_db[0x13][index].id != INVALID_TYPE) && (index < MAX_NUM_TYPES))
{
    printf("%s", data_db[0x13][index].name);
    index++;
}

对于您要完成的工作,这可能根本不起作用,并且取决于每组的类型数量,这可能完全浪费了代码空间。然而,这是解决问题的一种方式。

希望这可以帮助!

于 2013-04-16T00:43:21.570 回答