Otrzymuję pewne mylące zachowanie próbujące użyć wbudowanego c wyszukiwania w tablicy łańcuchów w C. Oto kod. Wiem, że możesz użyć wbudowanego strcmp do wyszukiwania tablic ciągów, ale włączyłem myStrCmp do celów debugowania, ponieważ nie wiedziałem, dlaczego to nie działa.Problemy z używaniem bsearch z tablicą łańcuchów znaków
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;
}
i tutaj jest część wyników, gdy ta funkcja jest wywoływana w poszukiwaniu Alabamy.
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
Jak widać, lokalizacje odwiedzane przez bsearch w trakcie jego poszukiwań powinien posiadać ważne ciągi (jak właśnie sprawdzana przed wywołaniem bsearch), ale wyjście jeśli próbujesz wydrukować char * na które lokalizacja to śmieci. Czy ktoś może zobaczyć mój błąd? Nawiasem mówiąc mam taką samą złe zachowanie (ale nie dostać do naśladowania go jako ściśle oczywiście) gdy zgłoszę bsearch z końcowym zestawu parametrów do:
(int(*)(const void*, const void*))strcmp
Dzięki!
Interesujące: to działa, czego nie oczekiwałem, że będzie gwarantowane przez standard. Jednakże, czytając ISO/IEC 9899: 2011, "§7.22.5.1 Funkcja" bsearch ", mówi: _¶3 Funkcja porównania wskazana przez" compar "jest wywoływana z dwoma argumentami, które wskazują na klucz obiektu i do elementu tablicy, w tej kolejności. Tak więc zachowanie jest deterministyczne. Nie można jednak użyć funkcji 'myStrCmp()' z 'qsort()'. –
@ JonathanLeffler: Tak, API jest zdefiniowane trochę inaczej niż dla 'qsort()', więc możesz podać ciąg znaków dla klucza, ale masz tablicę struktur do przeszukania. – jxh