排序数据库文件时,我在 c 中的 qsort 有问题?

I have a problem with qsort in c while sorting database file?

我是编程新手,我想使用 C 中的 qsort 函数进行数据库排序。

我们有一个 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 

您的问题可能出在比较功能上。 last_name 引用是指向 char 的指针,被声明为数组。您不需要星号 - 它只是获取数组中的第一个字符。

我将尝试解释一些指针和数组概念并将其与您的解决方案联系起来。为了更容易思考指针和内存space我喜欢将指向房屋地址和内存的指针space与houses/notes进行比较,我认为这对初学者有帮助。

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

char *Ina = 假设有一个名为 Ina 的指针(将其视为家庭地址)指向 char 类型的对象(房子里有一个 char)。

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

在另一个指针上使用 * 表示转到家庭住址的房子并告诉我里面是什么。现在你已经定义了 struct person_t ,它说明了房子里会有什么样的东西。除其他事项外,您还说过 person_t 房子将包含一个 char last_name[30]。你在这里说的是 person_t 房子将包含一张纸条(称为 last_name),其中包含一个包含字符的纸条的地址,并且房子中接下来的 29 个纸条也将恰好包含一个字符.

当使用 ((person_t *) pa) -> last_name 时,我们说的是去家庭地址为 pa 的房子(这是 person_t 的房子)。当我们在那所房子里时,我们想要得到便条(称为 last_name,包含另一个地址)和 return 它包含的内容。

当你使用 *((person_t *) pa) 进入房子 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 个注释(str1str2str3),每个注释包含一个带有字符的房子的地址,并且随后的 29 个房子也应该恰好包含一个特点。不过,我们从未说过这所房子有什么特征。这意味着此时房屋中可能有任何垃圾。

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

现在 strcpy 所做的是它转到第二个参数给出的地址所在的房子,并假设将有几个连续的房子包含字符并遍历所有这些直到有一个房子只包含一个 0,或者它达到了上限。现在它将使用类似的逻辑来填充第一个参数引用的房屋。 现在您需要问问自己,当您开始阅读时 str1 中实际包含什么?

fgetc() 将从文本文件中读取 return 个字符。 想想你如何在这里使用 fgetc() 以及你如何处理它 return 中的字符。你真的用过吗?

这是我对 SO 的第一个回答,非常感谢您的反馈! 希望能帮到你。