我收到一些令人困惑的行爲,試圖在C中的字符串數組上使用c內建bsearch。下面是代碼。我知道你可以使用內建的strcmp來搜索字符串數組,但是爲了調試的目的,我包含了myStrCmp,因爲我不知道它爲什麼不起作用。使用字符串數組使用bsearch時遇到問題
const char *stateNames[] = {"Alabama", "Alaska", "Arizona", "Arkansas", "California", "Colorado", "Connecticut", "Delaware", "Florida", "Georgia", "Hawaii", "Idaho", "Illinois", "Indiana", "Iowa", "Kansas", "Kentucky", "Louisiana", "Maine", "Maryland", "Massachusetts", "Michigan", "Minnesota", "Mississippi", "Missouri", "Montana", "Nebraska", "Nevada", "New Hampshire", "New Jersey", "New Mexico", "New York", "North Carolina", "North Dakota", "Ohio", "Oklahoma", "Oregon", "Pennsylvania", "Rhode Island", "South Carolina", "South Dakota", "Tennessee", "Texas", "Utah", "Vermont", "Virginia", "Washington", "Washington DC", "West Virginia", "Wisconsin", "Wyoming"};
int myStrCmp(const void *s1, const void *s2) {
printf("myStrCmp: s1(%p): %s, s2(%p): %s\n", s1, (char *)s1, s2, (char *)s2);
return strcmp(s1, s2);
}
int determineState(char *state) {
printf("state: %s\n", state);
for(int i = 0; i < 51; i++)
printf("stateNames[%i](%p): %s\n", i, &(stateNames[i]), stateNames[i]);
char *found = (char *) bsearch(state, stateNames, 51, sizeof(char *), myStrCmp);
if(found == NULL)
return -1;
return 0;
}
這裏是當這個函數被調用來尋找阿拉巴馬州時的一些輸出。
stateNames[0](0x618440): Alabama
stateNames[1](0x618448): Alaska
stateNames[2](0x618450): Arizona
...
stateNames[24](0x618500): Missouri
stateNames[25](0x618508): Montana
stateNames[26](0x618510): Nebraska
stateNames[27](0x618518): Nevada
stateNames[28](0x618520): New Hampshire
stateNames[29](0x618528): New Jersey
stateNames[30](0x618530): New Mexico
stateNames[31](0x618538): New York
stateNames[32](0x618540): North Carolina
stateNames[33](0x618548): North Dakota
stateNames[34](0x618550): Ohio
stateNames[35](0x618558): Oklahoma
stateNames[36](0x618560): Oregon
stateNames[37](0x618568): Pennsylvania
stateNames[38](0x618570): Rhode Island
stateNames[39](0x618578): South Carolina
stateNames[40](0x618580): South Dakota
stateNames[41](0x618588): Tennessee
stateNames[42](0x618590): Texas
stateNames[43](0x618598): Utah
stateNames[44](0x6185a0): Vermont
stateNames[45](0x6185a8): Virginia
stateNames[46](0x6185b0): Washington
stateNames[47](0x6185b8): Washington DC
stateNames[48](0x6185c0): West Virginia
stateNames[49](0x6185c8): Wisconsin
stateNames[50](0x6185d0): Wyoming
myStrCmp: s1(0x415430): Alabama, s2(0x618508):
UA
myStrCmp: s1(0x415430): Alabama, s2(0x618570): A
myStrCmp: s1(0x415430): Alabama, s2(0x618540): PUA
myStrCmp: s1(0x415430): Alabama, s2(0x618528): 1UA
myStrCmp: s1(0x415430): Alabama, s2(0x618538): GUA
myStrCmp: s1(0x415430): Alabama, s2(0x618530): <UA
正如你所看到的,在其搜索的過程中通過bsearch到過的地方應該有有效的字符串(如調用bsearch之前剛選中),但輸出,如果你嘗試打印字符*在那位置是垃圾。任何人都能看到我的錯誤?順便說一句,我得到了相同的不良行爲(但沒有得到遵循它作爲密切明顯)當我打電話bsearch與最終的參數設置爲:
(int(*)(const void*, const void*))strcmp
謝謝!
有趣的是,這工程,我沒有想到會被標準保證。但是,閱讀ISO/IEC 9899:2011,'§7.22.5.1'bsearch'函數',它會說:_¶3用'compar'指向的比較函數有兩個參數指向 指向關鍵對象,而到數組元素,按照這個順序。因此,行爲是確定性的。儘管如此,你不能在'qsort()'中使用'myStrCmp()'函數。 – 2013-04-05 05:08:00
@JonathanLeffler:是的,API的定義與'qsort()'有一點不同,這樣你就可以傳遞一個字符串作爲鍵,但有一個結構數組可以搜索。 – jxh 2013-04-05 05:49:55