struct数组的查找表索引

时间:2013-04-03 01:50:00

标签: c

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

典型地:

0x13 => FOO
0x14 => BAR

但是,实际上,可以存在多个相同类型的定义,然后是真实类型 在别处定义,但并不总是可以访问。所以我想 如果没有定义子规范,则打印所有可能性。

E.g:

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", ...}
}

然后有一个查找表,就像每个第一个条目的开始位置一样。这可以 当然也可以通过循环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
}

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

1 个答案:

答案 0 :(得分: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++;
}

这可能根本不适用于您要完成的任务,并且根据每组的类型数量,可能会完全浪费代码空间。但是,这是攻击问题的一种方法。

希望这有帮助!