【问题标题】:I have a problem with qsort in c while sorting database file?在对数据库文件进行排序时,我在 c 中遇到了 qsort 问题?
【发布时间】:2020-02-22 19:01:38
【问题描述】:

我是编程新手,我想使用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 

【问题讨论】:

  • 您没有从编译器获得任何诊断信息吗?请用-Werror编译!
  • 崩溃原因会给出警告
  • 您是否尝试在调试器中逐行运行程序,同时监视所有变量的值以查看它们是否具有您期望的值?您是否使用调试器来确定程序在哪一行导致了分段错误?
  • 第一个格式是%d,但是第一个打印的项目是一个字符串。
  • 完成 %d 个警告@stark

标签: c file sorting qsort fgetc


【解决方案1】:

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

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 房屋将包含一个便笺(称为姓氏),其中包含一个包含字符的便笺的地址,并且房屋中的以下 29 个便笺也将仅包含一个字符。

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

当您使用 *((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() 将从文本文件中读取并返回字符。 想想你如何在这里使用fgetc() 以及你如何处理它返回的字符。你真的用过吗?

这是我关于 SO 的第一个答案,因此我将不胜感激! 希望能帮上忙。

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-13
      相关资源
      最近更新 更多