2009-11-28 4 views
1

У меня есть файл несортированного словаря с именем "dict.txt". Мне удалось помещать слова файла в массив, и используемое мной qsort() также работает очень хорошо (т. Е. Массив отсортирован).Почему вызов bsearch() приводит к сбою представленной программы?

Проблема возникает, когда я называю bsearch(), сбои программы и мой вопрос:

Почему это происходит?

Я использую gcc для компиляции и не использую IDE любого типа, поэтому у меня нет отладчика, и я не знаю, как его использовать (пока).

Я прекрасно понимаю, что представленный здесь код может содержать несколько проблем.

Это потому, что я довольно новичок в c, а мой фон - это в основном Java (который, несмотря на сходство, кажется, является недостатком, потому что я так привык к OO и c, очевидно, не OO).

Любые советы были бы весьма полезными.

int strcmp_mod(const void *p1, const void *p2) { 
    return strcmp(* (char * const *) p1, * (char * const *) p2); 
} 

int main(void) { 

int size, i; 
char **words; 

char *pItem; 
char *key = "fight"; 

char* buf = load_file("dict.txt"); if (buf == NULL) return 1; 

size = count_words(buf); 

words = (char**)malloc((size+1) * sizeof(char*)); 

for (i=0; i<size; i++) { 
    words[i] = (char*)malloc(80 * sizeof(char)); 
} 

copy_words_to_lower(buf, words, size); 
    words[size] = '\0'; 

    qsort(words, size, sizeof(char*), strcmp_mod); 

for (i=0; i<size; i++) { 
    printf("%s\n", words[i]); 
} 

pItem = (char *) bsearch(key, words, size, sizeof(char*), strcmp_mod); 

if (pItem!=NULL) 
    printf ("%s is in the array.\n", pItem); 
else 
    printf ("%s is not in the array.\n", key); 

return 0; 
} 
+1

Попробуйте поместить printf() в вашу функцию strcmp_mod ..., которая позволит вам точно увидеть, что сравнивается с чем (и является ли это даже допустимой строкой), чтобы вы могли точно видеть, что происходит, даже без отладчик. – Eric

ответ

2

Попробуйте дать bsearchадрес из key.

+0

+1 избили меня. –

+0

Большое спасибо. – dankilman

2

Почему это происходит?

Вы пропусканием char* как параметр key для bsearch, но ваш компаратор ожидает результат литья char** к мочеиспусканию *.

Как только вы исправили это, следующая проблема заключается в том, что возвращаемое значение из bsearch является указателем на соответствующий элемент в массиве. Так снова char** не char*.

Любые советы были бы весьма признательны.

Либо получите отладчик, либо приготовьтесь добавить много кода в свой код.

Кроме того, конструкция вашего массива words слегка отключена. Поскольку он выполняет эту работу, но может быть идея выделить буфер для каждого слова, когда вы идете, а не все одинаковые размеры в начале. Кто знает, если кто-то отправит вам файл со словом в нем более 80 символов? Вы завершаете список слов символом nul , '\ 0', когда вы, вероятно, имеете в виду его завершение нулевым указателем , NULL. '\ 0' на самом деле работает, потому что это еще один способ сказать 0 и 0 преобразуется в нулевой указатель. Но это не то, что вы имеете в виду. И массив не обязательно должен быть завершен с нулевой отметкой сейчас, потому что каждый раз, когда вы используете его после этого, вы указываете его длину, size.

+0

Отличный ответ. У меня вопрос о распределении буфера, когда я иду. , когда я пытаюсь использовать тот же синтаксис внутри copy_words_to_lower() после проверки длины текущего слова, я также выкидываю при использовании malloc(), и я получаю сообщение об ошибке, связанном с доступом к некоторому адресу памяти, который является не допускается. Вот почему я изначально выставлял его снаружи, поскольку он, казалось, работал таким образом. Какой-нибудь большой совет по этому вопросу? – dankilman

+0

нашел это ... спасибо вам в любом случае. – dankilman

+0

Другим вариантом было бы не выделять буферы для каждого слова вообще. Вы не используете его ни для чего другого, так что вы можете, возможно, изменить данные в 'buf'. Напишите NUL-байт в конце каждого слова (я предполагаю, что в настоящее время есть пробелы или разрывы строк между словами?), Замените любые заглавные буквы строчными буквами и напишите указатель на начало каждого слова в «слова» массив. Исходя из Java, это, вероятно, кажется немного взломанным, просто превращая одну большую строку во много маленьких, но избежать слишком большого выделения памяти часто вызывает озабоченность в практическом коде C. –

Смежные вопросы