У меня проблема с qsort в c при сортировке файла базы данных? - PullRequest
0 голосов
/ 22 февраля 2020

Я новичок в программировании, я хочу выполнить сортировку базы данных, используя функцию qsort в C.

у нас есть файл из 100 человек, я хочу отсортировать его по фамилиям, считав данные из текстового файла в переменную базы данных из 100 человек и набрав struct. Я новичок в этом.

Это мой код:

  int compare(const void *pa,const void *pb)
{
  char *Ina = *((person_t*)pa)->last_name;
  char *Inb = *((person_t*)pb)->last_name;
   return strcmp(Ina,Inb);
};


    while(fgetc(fp)!= EOF)
    {
        strcpy(dbasepeople[ctr].last_name,str1);
        strcpy(dbasepeople[ctr].first_name,str2);
        strcpy(dbasepeople[ctr].city_name,str3);
    ++ ctr;  
    } 

, поэтому я получил эту ошибку или вывод, которого я не хочу.

297608 ���� ��e2� -1674750400 0                                                                                                
6297698 ���� ��e2� -1674750400 0                                                                                                
6297788 ���� ��e2� -1674750400 0                                                                                                
6297878 ���� ��e2� -1674750400 0                                                                                                
6297968 ���� ��e2� -1674750400 0                                                                                                
6298058 ���� ��e2� -1674750400 0                                                                                                
6298148 ���� ��e2� -1674750400 0                                                                                                
6298238 ���� ��e2� -1674750400 0                                                                                                
6298328 ���� ��e2� -1674750400 0                                                                                                
Segmentation fault (core dumped)

предупреждения, которые я получаю, являются

main.c:16:15: warning: initialization makes pointer from integer without a cast [-Wint-conversion]                       
main.c:17:15: warning: initialization makes pointer from integer without a cast [-Wint-conversion]                       
Before sorting:                                                                                                          
6295808 ���� P|�t� -1 0                                                                                                  
6295898 ���� P|�t� 873305664 0                                                                                           
6295988 ���� P|�t� 873305664 0                                                                                           
6296078 ���� P|�t� 873305664 0                                                                                           
6296168 ���� P|�t� 873305664 0 

Ответы [ 2 ]

1 голос
/ 23 февраля 2020

Я попытаюсь объяснить некоторые концепции указателей и массивов и t ie в вашем решении. Чтобы было легче думать об указателях и пространстве памяти, мне нравится сравнивать указатели с адресами домов, а пространство памяти с домами / заметками, думаю, это полезно для начинающих.

char *Ina = *((person_t*)pa)->last_name; char *Inb = *((person_t*)pb)->last_name;

char *Ina = Пусть будет указатель по имени Ина (представьте его как домашний адрес) на что-то, имеющее тип char (в доме живет char).

*((person_t*)pa)->last_name;

Использование * на другом указателе означает go на дом домашнего адреса и даст мне то, что внутри. Теперь вы определили struct person_t, который говорит, что за вещи будут в доме. Среди прочего вы сказали, что в доме person_t будет char last_name[30]. Здесь вы говорите, что дом person_t будет содержать заметку (называемую last_name) с адресом заметки, содержащей символ, и следующие 29 заметок в доме также будут содержать ровно один символ.

При использовании ((person_t *) pa) -> last_name мы говорим go дому с домашним адресом pa (который является person_t домом). Когда мы находимся в этом доме, мы хотим получить записку (называемую last_name, содержащую другой адрес) и вернуть то, что в ней содержится.

Когда вы используете *((person_t *) pa), вы входите в дом и вы нарисует персонажа на первой ноте в доме. На данный момент мы имеем дело с реальным символом, с которым нет адресов для подражания.

Теперь давайте посмотрим на второй номер

   char str1[30],str2[30],str3[30];

   FILE *fp;
   fp=fopen("words.txt","r");
   if(fp==NULL)
   { 
   printf("\n Cannot open the file \n");
   exit(0);
   }
   while(fgetc(fp)!= EOF)
   {
       strcpy(dbasepeople[ctr].last_name,str1);
       strcpy(dbasepeople[ctr].first_name,str2);
       strcpy(dbasepeople[ctr].city_name,str3);
   ++ ctr;  
   } 

Что это значит? char str1[30],str2[30],str3[30]; Здесь мы говорим, что должно быть 3 примечания (str1, str2, str3), каждая из которых содержит адрес для дома с персонажем, а последующие 29 домов также должны содержать ровно один символ. Мы никогда не говорили, какого характера содержит дом. Это означает, что на данный момент в домах может быть любой мусор.

strcpy(dbasepeople[ctr].last_name,str1);

Теперь, что делает strcpy, так это то, что он идет в дом адресов, заданных вторыми аргументами, и предполагает, что в строке будет несколько домов, содержащих символы и go через все из них, пока не появится дом, содержащий только 0, или пока он не достигнет верхнего предела. Теперь он будет использовать аналогичные логики c для заполнения домов, на которые ссылается первый аргумент. Теперь вам нужно спросить себя, что на самом деле будет в str1, когда вы начнете читать с него?

fgetc() будет читать и возвращать символы из текстового файла. Подумайте, как вы используете fgetc() здесь и что вы делаете с символами, которые он возвращает. Вы когда-нибудь использовали их?

Это мой первый ответ на SO, поэтому я буду признателен за обратную связь! Я надеюсь, что смогу помочь.

0 голосов
/ 23 февраля 2020

Ваша проблема может быть в функции сравнения. Ссылка на last_name является указателем на char, который объявляется как массив. Вам не нужна звезда - она ​​просто получает первый символ в массиве.

...