麻烦使用bsearch与字符串数组

我试图在C中的字符串数组上使用c builtin bsearch时遇到一些令人困惑的行为。这是代码。 我知道你可以使用内置的strcmp来搜索字符串数组,但我包含myStrCmp用于调试目的,因为我不知道为什么它不起作用。

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

这是调用此函数寻找Alabama时的一些输出。

 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之前一样检查过),但是如果您尝试在该位置打印char *则输出是垃圾。 谁能看到我的错误? 顺便说一下,当我调用bsearch并将最终参数设置为:时,我会得到相同的不良行为(但不要明显地遵循它)

 (int(*)(const void*, const void*))strcmp 

谢谢!

由于您使用的是const char *数组, bsearch()会将指向这些元素的指针传递给比较函数。 换句话说,它将在其第二个参数中接收const char * const *

 int myStrCmp(const void *s1, const void *s2) { const char *key = s1; const char * const *arg = s2; printf("myStrCmp: s1(%p): %s, s2(%p): %s\n", s1, key, s2, *arg); return strcmp(key, *arg); } 

您的州名(或键)需要是指针的指针。 没有必要在任何地方添加/删除constmyStrCmp需要通过一个解除引用来比较字符串。 下面的代码可以实现您的想法。 如果没有,请告诉我,谢谢。

 #include  #include  #include  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(*(char **) s1, *(char **) 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; } else { printf("Found it!: %s\n", *found); } return 0; } int main(int argc, const char * argv[]) { determineState("Alabama"); }