2016-01-12 48 views
2

通過POSIX hcreate/hsearch功能implented使用關聯數組(如描述here,我掙扎着,我從來沒有進入一些意外的行爲尋找鑰匙或周圍的其他方法。 我跟蹤它到商店按引用的一些實例-instead-的價值 這令我感到詫異,因爲在該示例使用字符串文字作爲關鍵字:如何在C中通過hcreate/hsearch(通過值而不是引用)實現關聯數組的鍵?

store("red", 0xff0000); 
store("orange", 0x123456); /* Insert wrong value! */ 
store("green", 0x008000); 
store("blue", 0x0000ff); 
store("white", 0xffffff); 
store("black", 0x000000); 
store("orange", 0xffa500); /* Replace with correct value. */ 

這裏是一個MWE,顯示我的問題:

#include <inttypes.h> /* intptr_t    */ 
#include <search.h> /* hcreate(), hsearch() */ 
#include <stdio.h> /* perror()    */ 
#include <stdlib.h> /* exit()    */ 
#include <string.h> /* strcpy()    */ 

void exit_with_error(const char* error_message){ 
    perror(error_message); 
    exit(EXIT_FAILURE); 
} 
int fetch(const char* key, intptr_t* value){ 
    ENTRY e,*p; 
    e.key=(char*)key; 
    p=hsearch(e, FIND); 
    if(!p) return 0; 
    *value=(intptr_t)p->data; 
    return 1; 
} 

void store(const char *key, intptr_t value){ 
    ENTRY e,*p; 
    e.key=(char*)key; 
    p = hsearch(e, ENTER); 
    if(!p) exit_with_error("hash full"); 
    p->data = (void *)value; 
} 

void main(){ 
    char a[4]="foo"; 
    char b[4]="bar"; 
    char c[4]=""; 
    intptr_t x=NULL; 

    if(!hcreate(50)) exit_with_error("no hash"); 

    store(a,1); /* a --> 1 */ 
    strcpy(c,a); /* remember a */ 
    strcpy(a,b); /* set a to b */ 
    store(a,-1); /* b --> -1 */ 
    strcpy(a,c); /* reset a */ 

    if(fetch(a,&x)&&x==1) puts("a is here."); 
    if(!fetch(b,&x)) puts("b is not."); 
    strcpy(a,b); printf("But if we adjust a to match b"); 
    if(fetch(a,&x)&&x==-1&&fetch(b,&x)&&x==-1) puts(", we find both."); 
    exit(EXIT_SUCCESS); 
} 

Compili Ng和上述C代碼產生以下輸出執行:

a is here. 
b is not. 
But if we adjust a to match b, we find both. 

我將需要讀取文件,並存儲了一大批串:整數對,然後我需要閱讀的第二文件,以檢查偶數以前存儲的值的字符串數量較多。

我不明白如果通過引用來比較鍵,這將如何實現。

如何更改我的關聯數組實現以按值存儲鍵?

如果這是不可能的,那麼考慮到上述用例,我該如何解決這個問題?


編輯:

這個問題只涉及與輸入密鑰,但沒有找到。 也會出現相反的問題,並在this question中詳細介紹。

+0

[C hsearch找到之前未輸入的值]的可能重複(http://stackoverflow.com/questions/34752934/c-hsearch-finds-values-not-entered-before) – mschilli

回答

1

編輯:

原來store()需要strdup()key解決這一問題,並another problem


我發現,通過使用相同的變量進行存儲&查找,我實際上可以在陣列中檢索所有的值:

void main(){ 
char a[4]="foo"; 
    char b[4]="bar"; 
    char c[4]="baz"; 
    char t[4]=""; 
    intptr_t x=NULL; 

    if(!hcreate(50)) exit_with_error("no hash"); 

    strcpy(t,a); store(t, 1); /* a --> 1 */ 
    strcpy(t,b); store(t,-1); /* b --> -1 */ 
    strcpy(t,c); store(t, 0); /* c --> 0 */ 

    if(!fetch(a,&x)) puts("a is not here."); 
    if(!fetch(b,&x)) puts("Neither is b."); 
    if(fetch(c,&x)) puts("c is in (and equal to t)."); 

    strcpy(t,a); if(fetch(t,&x)&&x== 1) puts("t can retrieve a."); 
    strcpy(t,b); if(fetch(t,&x)&&x==-1) puts("It also finds b."); 
    strcpy(t,c); if(fetch(t,&x)&&x== 0) puts("And as expected c."); 

    exit(EXIT_SUCCESS); 
} 

這導致下面的輸出:

a is not here. 
Neither is b. 
c is in (and equal to t). 
t can retrieve a. 
It also finds b. 
And as expected c. 

但是,我仍然不明白爲什麼會發生這種情況。

不知怎麼,它似乎是關鍵需要在同一位置(參考)包含相同的內容(價值)被發現。

+0

即使這不適用於我。最後,我放棄hsearchand將尋找私人散列函數 –

+0

@mk:如果您將問題發佈爲問題並將其鏈接到此處,我可能會提供幫助。 – mschilli

相關問題