鱼C论坛

 找回密码
 立即注册
查看: 4534|回复: 58

[已解决]在身份证中提取出生日期并排序,球球大佬帮忙看看为啥使用的qsort出现segemetionfault

[复制链接]
发表于 2022-11-28 17:56:43 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. int compare(const void *e1,const void *e2)
  5. {
  6.    return strcmp(*(char **)e1,*(char **)e2);
  7. }
  8. //身份证排序
  9. int main()
  10. {
  11.     char a[3][18]={'\0'},b[3][18]={'\0'};
  12.     int i,j,k;
  13. //输入
  14.     for(i=0;i<3;i++)
  15.     {
  16.         scanf("%s",a[i]);
  17.     }
  18.     //提取出生日期
  19. for(j=0;j<3;j++)
  20.    {
  21.     for(i=6,k=0;i<14,k<8;i++,k++)
  22.     {
  23.         b[j][k]=a[j][i];
  24.     }
  25.     }
  26.     //打印出生日期
  27.     for(i=0;i<3;i++)
  28.     {

  29.         printf("%s\n",b[i]);
  30.     }
  31. //排序
  32.     qsort(b,3,sizeof(b[0]),compare);
  33.    
  34.     for(i=0;i<3;i++)
  35.     {
  36.      printf("%s\n",b[i]);
  37.     }

  38.     return 0;
  39. }
复制代码
最佳答案
2022-11-28 19:26:17
本帖最后由 zhangjinxuan 于 2022-11-28 19:28 编辑

比较函数写的有点问题啊
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. int compare(const void *e1,const void *e2)
  5. {
  6.    return strcmp((char*)e1,(char*)e2); //应该要这么写
  7. }
  8. int main()
  9. {
  10.     char a[3][18]={'\0'},b[3][18]={'\0'};
  11.     int i,j,k;
  12.     for(i=0;i<3;i++)
  13.     {
  14.         scanf("%s",a[i]);
  15.     }
  16. for(j=0;j<3;j++)
  17.    {
  18.     for(i=6,k=0;i<14,k<8;i++,k++)
  19.     {
  20.         b[j][k]=a[j][i];
  21.     }
  22.     }
  23.     for(i=0;i<3;i++)
  24.     {

  25.         printf("%s\n",b[i]);
  26.     }
  27.     qsort(b,3,sizeof(b[0]),compare);
  28.     for(i=0;i<3;i++)
  29.     {
  30.      printf("%s\n",b[i]);
  31.     }

  32.     return 0;
  33. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2022-11-28 19:26:17 | 显示全部楼层    本楼为最佳答案   
本帖最后由 zhangjinxuan 于 2022-11-28 19:28 编辑

比较函数写的有点问题啊
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. int compare(const void *e1,const void *e2)
  5. {
  6.    return strcmp((char*)e1,(char*)e2); //应该要这么写
  7. }
  8. int main()
  9. {
  10.     char a[3][18]={'\0'},b[3][18]={'\0'};
  11.     int i,j,k;
  12.     for(i=0;i<3;i++)
  13.     {
  14.         scanf("%s",a[i]);
  15.     }
  16. for(j=0;j<3;j++)
  17.    {
  18.     for(i=6,k=0;i<14,k<8;i++,k++)
  19.     {
  20.         b[j][k]=a[j][i];
  21.     }
  22.     }
  23.     for(i=0;i<3;i++)
  24.     {

  25.         printf("%s\n",b[i]);
  26.     }
  27.     qsort(b,3,sizeof(b[0]),compare);
  28.     for(i=0;i<3;i++)
  29.     {
  30.      printf("%s\n",b[i]);
  31.     }

  32.     return 0;
  33. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-11-28 19:44:59 | 显示全部楼层
如果像你这么写:
  1. strcmp(*(char **)e1,*(char **)e2);
复制代码

我们来解析一下, (char*) e1 就可以把 void * 的 e1 转换成 char * 的 e1,这时又来了一个星号,意思就是 e1 的第一个字符,所以 (char**) e1 返回的就是一个 char

之后如果你再对一个 char 进行解引用是不是就段错误了?

正确的:
  1. strcmp((char*)e1,(char*)e2);
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-11-28 19:46:20 | 显示全部楼层
zhangjinxuan 发表于 2022-11-28 19:26
比较函数写的有点问题啊

那么为啥这个给字符串排序用您那种办法就不行捏?用我这种才正确,我有点懵了,呜呜呜
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. int compare(const void *e1,const void *e2)
  5. {
  6.       return strcmp(*(char**)e1,*(char**)e2);
  7. }
  8. int main()
  9. {
  10.     char**a;
  11.     char ch[100];
  12.     int n=10,i,j;
  13. //创建二维指针                  
  14.     a=(char**)malloc(n*sizeof(char*));
  15.     if(a==NULL)
  16.     {
  17.         free(a);
  18.         exit(1);
  19.     }
  20.     for(i=0;i<n;i++)
  21.     {
  22.         a[i]=(char*)malloc(100*sizeof(char));
  23.         if(a[i]==NULL)
  24.         {
  25.             for( j=0;j<=i;j++)
  26.                 free(a[j]);
  27.         }
  28.     }
  29.     //输入
  30.     for(i=0;i<n;i++)
  31.     {
  32.         scanf("%s",a[i]);
  33.     }
  34.    // 排序
  35.     qsort(a,n,sizeof(a[0]),compare);
  36.     //打印
  37.     for(i=0;i<n-1;i++)
  38.     {
  39.         printf("%s\n",a[i]);
  40.     }
  41.    
  42.     printf("%s",a[i]);
  43.     printf("\n");
  44.     // free掉
  45.     for(i=0;i<n;i++)
  46.     {
  47.         free(a[i]);
  48.     }
  49.     free(a);
  50.     return 0;
  51. }

复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-11-28 19:56:19 From FishC Mobile | 显示全部楼层
zwj.123 发表于 2022-11-28 19:46
那么为啥这个给字符串排序用您那种办法就不行捏?用我这种才正确,我有点懵了,呜呜呜

看看3楼,我发了更详细的解释
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-11-28 19:57:11 From FishC Mobile | 显示全部楼层
zwj.123 发表于 2022-11-28 19:46
那么为啥这个给字符串排序用您那种办法就不行捏?用我这种才正确,我有点懵了,呜呜呜

(char*)e1 已经是一个字符指针(字符串),不用写这么麻烦
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-11-28 20:06:02 | 显示全部楼层
zhangjinxuan 发表于 2022-11-28 19:44
如果像你这么写:

我们来解析一下, (char*) e1 就可以把 void * 的 e1 转换成 char * 的 e1,这时又来了 ...

我可能有点笨哈哈,很抱歉,可以麻烦你一下在解释下嘛,我没怎么看明白,如果您没空就算了吧。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-11-28 20:07:28 | 显示全部楼层
zhangjinxuan 发表于 2022-11-28 19:57
(char*)e1 已经是一个字符指针(字符串),不用写这么麻烦

但是我如果不用二维指针那种办法他也有问题,呜呜呜
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-11-28 20:10:51 From FishC Mobile | 显示全部楼层
zwj.123 发表于 2022-11-28 20:06
我可能有点笨哈哈,很抱歉,可以麻烦你一下在解释下嘛,我没怎么看明白,如果您没空就算了吧。

不好意思,说错了,你想一想,strcmp的参数是什么,是char*对吧,所以只要转换成char*就可以了,不用写这么麻烦,现在用手机,不好操作,解释有点不好写,不好意思
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-11-28 20:11:26 From FishC Mobile | 显示全部楼层
zwj.123 发表于 2022-11-28 20:07
但是我如果不用二维指针那种办法他也有问题,呜呜呜

神马?我的没有报错?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-11-28 20:12:38 From FishC Mobile | 显示全部楼层
zwj.123 发表于 2022-11-28 20:07
但是我如果不用二维指针那种办法他也有问题,呜呜呜

我这么写是可以通过的
strcmp((char*)e1,(char*)e2)
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-11-28 20:14:31 From FishC Mobile | 显示全部楼层
zwj.123 发表于 2022-11-28 20:07
但是我如果不用二维指针那种办法他也有问题,呜呜呜

是什么就转什么类型,不要写的很麻烦,因为strcmp的参数本来就是char*,就可以不用二维指针了
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-11-28 20:30:41 | 显示全部楼层
zhangjinxuan 发表于 2022-11-28 20:10
不好意思,说错了,你想一想,strcmp的参数是什么,是char*对吧,所以只要转换成char*就可以了,不用写这 ...

没事的,哈哈
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-11-28 20:33:24 | 显示全部楼层

好了,你还有什么疑问吗?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-11-28 20:35:33 | 显示全部楼层
zhangjinxuan 发表于 2022-11-28 20:33
好了,你还有什么疑问吗?

还是很疑惑
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-11-28 20:36:29 | 显示全部楼层
就是这个代码,不用这种办法它排序出来就有问题,呜呜呜
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #define n 3
  5. int compare(const void *e1,const void *e2)
  6. {
  7.       return strcmp(*(char**)e1,*(char**)e2);
  8. }
  9. int main()
  10. {
  11.     char**a;
  12.     char ch[100];
  13.     int i,j;
  14. //创建二维指针                  
  15.     a=(char**)malloc(n*sizeof(char*));
  16.     if(a==NULL)
  17.     {
  18.         free(a);
  19.         exit(1);
  20.     }
  21.     for(i=0;i<n;i++)
  22.     {
  23.         a[i]=(char*)malloc(100*sizeof(char));
  24.         if(a[i]==NULL)
  25.         {
  26.             for( j=0;j<=i;j++)
  27.                 free(a[j]);
  28.         }
  29.     }
  30.     //输入
  31.     for(i=0;i<n;i++)
  32.     {
  33.         scanf("%s",a[i]);
  34.     }
  35.    // 排序
  36.     qsort(a,n,sizeof(a[0]),compare);
  37.     //打印
  38.     for(i=0;i<n-1;i++)
  39.     {
  40.         printf("%s\n",a[i]);
  41.     }
  42.    
  43.     printf("%s",a[i]);
  44.     printf("\n");
  45.     // free掉
  46.     for(i=0;i<n;i++)
  47.     {
  48.         free(a[i]);
  49.     }
  50.     free(a);
  51.     return 0;
  52. }

复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-11-28 20:38:01 | 显示全部楼层
zhangjinxuan 发表于 2022-11-28 20:12
我这么写是可以通过的
strcmp((char*)e1,(char*)e2)

呜呜呜,为啥,我换个编译器试试
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-11-28 20:40:23 | 显示全部楼层
zwj.123 发表于 2022-11-28 20:36
就是这个代码,不用这种办法它排序出来就有问题,呜呜呜

神马玩意儿?我的没问题?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-11-28 20:41:01 | 显示全部楼层
zhangjinxuan 发表于 2022-11-28 20:12
我这么写是可以通过的
strcmp((char*)e1,(char*)e2)

的确可以通过的,但是它排序后的结果有问题,呜呜呜
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-11-28 20:42:48 | 显示全部楼层
zwj.123 发表于 2022-11-28 20:41
的确可以通过的,但是它排序后的结果有问题,呜呜呜

我明天再试试吧,我都晕了
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-4-23 01:06

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表