Cの組み込みのbsearchをCの文字列に使用しようとすると、混乱します。ここにコードがあります。私はあなたが文字列の配列を検索するための組み込み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'が指す比較関数は、キーオブジェクトに対して を指す2つの引数で呼び出され、配列要素にその順番で並べ替えます。したがって、振る舞いは確定的です。しかし、 'mystrCmp()'関数を 'qsort()'と一緒に使うことはできませんでした。 –
@JonathanLeffler:ええ、APIは 'qsort()'と少し違って定義されているので、キーの文字列を渡すことができますが、検索する構造体の配列を持つことができます。 – jxh