2013-04-03 77 views
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", ...} 
    } 
} 

在o以便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 
} 

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

+0

您的方法存在根本上的缺陷。没有更多信息,你无法做到这一点。你正在尝试使用* not * unique作为唯一标识符。只给出一个数字,你不能确定它是指'foo'还是'bar'或'whatever'。你需要一个不同的方法。 –

+1

相信你错过了这一点。正如我写的,我想列出所有类型的相同标识符。如果0x14有两种类型,我想列出这两种。所以我会有一个**组**的唯一标识符 - 我通过索引数组获得。此外,数据输入来自外部来源,并且由于历史原因,类型/ ID是重叠的。 – Zimzalabim

+2

好的,对不起,我想我是。然而,很显然,如果一个值可以映射到N个值,那么您需要一个值=>集合映射。这意味着,在最基本的层面上,您需要一个数组数组,其中索引映射到N个结构实例。你最好的选择将是一个关联容器,C标准库中不存在任何关联容器。当然,这个问题*已经解决了许多次,并且存在许多第三方解决方案 –

回答

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++; 
} 

这可能不是在所有的工作对你想要什么来完成,并根据每个组类型的数量,也可能是代码空间完全是浪费。但是,这是解决问题的一种方法。

希望这有助于!

+0

只需使用一个函数指针来确定类型是否有效?或者我错过了什么......然后查看真正的值......更小更快...... – Jay

+0

@Jay你有没有可以发布的例子? –

+0

+1。但;它是256个ID,其中大约50个具有范围从2到6的重复。这意味着“256 * 6”,因此我有点大。 (不是你可以从我在Q中提供的信息中知道)。 - 我正在考虑使用更复杂的索引数组,但由于其他优先项目,整个项目最近一直处于冻结模式。 – Zimzalabim