Tôi đang nhận được một số hành vi khó hiểu đang cố gắng sử dụng công cụ tìm kiếm dựng sẵn c trên một chuỗi các chuỗi trong C. Đây là mã. Tôi biết bạn có thể sử dụng strcmp dựng sẵn để tìm kiếm chuỗi các chuỗi, nhưng tôi đã bao gồm myStrCmp cho mục đích gỡ lỗi vì tôi không biết tại sao nó không hoạt động.Gặp sự cố khi sử dụng bsearch với một chuỗi các chuỗi
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;
}
và đây là một số đầu ra khi chức năng này được gọi để tìm 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
Như bạn có thể thấy, các địa điểm viếng thăm bởi bsearch trong quá trình tìm kiếm của mình nên có các chuỗi giá trị (như đã được chỉ cần kiểm tra trước khi gọi bsearch), nhưng sản lượng nếu bạn cố gắng in char * ở đó vị trí là rác. Có ai có thể thấy sai lầm của tôi không? Ngẫu nhiên tôi nhận được cùng một hành vi xấu (nhưng không được theo dõi nó rõ ràng) khi tôi gọi bsearch với tham số cuối cùng được đặt thành:
(int(*)(const void*, const void*))strcmp
Cảm ơn!
Thú vị: hoạt động mà tôi không mong đợi được đảm bảo theo tiêu chuẩn. Tuy nhiên, đọc ISO/IEC 9899: 2011, '§7.22.5.1 Chức năng 'bsearch'', nó nói: _¶3 Hàm so sánh được trỏ đến bởi' so sánh' được gọi với hai đối số trỏ tới đối tượng khóa và thành phần tử mảng, theo thứ tự đó._ Vì vậy, hành vi là xác định. Tuy nhiên, bạn không thể sử dụng hàm 'myStrCmp()' đó với 'qsort()'. –
@JonathanLeffler: Vâng, API được định nghĩa khác một chút so với 'qsort()' để bạn có thể chuyển một chuỗi cho khóa, nhưng có một mảng cấu trúc để tìm kiếm thông qua. – jxh