我收到一些令人困惑的行为,试图在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