2013-04-03 101 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