在C中对名称和ID进行排序

问题描述 投票:0回答:3

我试着编写一个可以对名称进行排序的代码。所以我试图编写一个程序,但它不能按我的意愿工作。我希望名称按字母顺序排序。我还想根据哪个id具有最高值来对id进行排序。所有帮助赞赏。有点新的C和编码一般!

#include <stdio.h>
#include <stdlib.h>

struct class {
  char gender[13];
  char name[13];
  int *id;
};

int compare(const void *s1, const void *s2)
{
  struct class  *e1 = (struct class *)s1;
  struct class *e2 = (struct class *)s2;
  int gendercompare = strcmp(e1->name, e2->name);
  if (gendercompare == 0)  
    return e2->gender - e1->gender;
  else
    return -gendercompare;
}

main()
{
  int i;
  int employeecount;

  struct class info[]={{"male","AAA",2000},{"female","BBB",1000},{"male","CCC",3000}};

  employeecount=3; 

  for (i = 0; i < employeecount; ++i)
    printf("%i\t%s\t%s\n", info[i].id, info[i].gender, info[i].name);
    printf("\n");

  qsort(info, 3, sizeof(struct class), compare);

  for (i = 0; i < employeecount; ++i)
    printf("%i\t%s\t%s\n", info[i].id, info[i].gender, info[i].name);
}
c
3个回答
1
投票

我想您可能需要更新您的compare函数,如下所示:

#include <string.h>

struct class {
  char gender[13];
  char name[13];
  int id;
};

int compare(const void *s1, const void *s2)
{
  struct class *e1 = (struct class *)s1;
  struct class *e2 = (struct class *)s2;
  return strcmp(e1->gender, e2->gender);
}

strcmp足以进行比较。

在@ Jabberwocky的答案中,很好地提到了其他一些细节。


1
投票

有几个问题,请参阅我添加的// <<<<评论:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>   // <<<< you forgot to include string.h

struct class {
  char gender[13];
  char name[13];
  int id;            // <<<< int *id; having a pointer here is pointless,
                     //      you simple want an integer value here.
                     //      That's the main problem in your code
};

int compare(const void *s1, const void *s2)
{
  struct class *e1 = (struct class *)s1;
  struct class *e2 = (struct class *)s2;
  int gendercompare = strcmp(e1->name, e2->name);
  if (gendercompare == 0)
    return e2->gender - e1->gender;
  else
    return -gendercompare;
}

int main(void)   // <<<< it's int main(void) , not main()
{
  int i;
  int employeecount;

  struct class info[] = { {"male","AAA",2000},{"female","BBB",1000},{"male","CCC",3000} };

  employeecount = 3;

  for (i = 0; i < employeecount; ++i)
    printf("%i\t%s\t%s\n", info[i].id, info[i].gender, info[i].name);
  printf("\n");

  // <<<< use employeecount instead of 3, it's the same thing but it's more consistent.
  //      Not something that would prevent your code from working
  qsort(info, employeecount, sizeof(struct class), compare);

  for (i = 0; i < employeecount; ++i)
    printf("%i\t%s\t%s\n", info[i].id, info[i].gender, info[i].name);
}

在你的compare函数中也有一个逻辑问题,似乎你想按性别排序,首先是男性。

由于compare函数必须返回值<0,0或> 0,因此您只需返回strcmp的返回值。你也不需要演员表,但e1e2必须是const,因为s1s2const

int compare(const void *s1, const void *s2)
{
  const struct class *e1 = s1;
  const struct class *e2 = s2;
  return -strcmp(e1->gender, e2->gender);
}

另请参阅ConsistentProgrammer对按名称排序的比较函数的答案。


0
投票

编译并启用更多警告,以帮助您诊断问题:

gcc -std=c17 -fPIC -g -Wall -Wextra -Wwrite-strings -Wno-parentheses -Wpedantic -Warray-bounds         54908259.c    -o 54908259
54908259.c: In function ‘compare’:
54908259.c:14:23: warning: implicit declaration of function ‘strcmp’ [-Wimplicit-function-declaration]
   int gendercompare = strcmp(e1->name, e2->name);
                       ^~~~~~
54908259.c: At top level:
54908259.c:21:1: warning: return type defaults to ‘int’ [-Wimplicit-int]
 main()
 ^~~~
54908259.c: In function ‘main’:
54908259.c:26:38: warning: initialization of ‘int *’ from ‘int’ makes pointer from integer without a cast [-Wint-conversion]
   struct class info[]={{"male","AAA",2000},{"female","BBB",1000},{"male","CCC",3000}};
                                      ^~~~
54908259.c:26:38: note: (near initialization for ‘info[0].id’)
54908259.c:26:60: warning: initialization of ‘int *’ from ‘int’ makes pointer from integer without a cast [-Wint-conversion]
   struct class info[]={{"male","AAA",2000},{"female","BBB",1000},{"male","CCC",3000}};
                                                            ^~~~
54908259.c:26:60: note: (near initialization for ‘info[1].id’)
54908259.c:26:80: warning: initialization of ‘int *’ from ‘int’ makes pointer from integer without a cast [-Wint-conversion]
   struct class info[]={{"male","AAA",2000},{"female","BBB",1000},{"male","CCC",3000}};
                                                                                ^~~~
54908259.c:26:80: note: (near initialization for ‘info[2].id’)
54908259.c:31:14: warning: format ‘%i’ expects argument of type ‘int’, but argument 2 has type ‘int *’ [-Wformat=]
     printf("%i\t%s\t%s\n", info[i].id, info[i].gender, info[i].name);
             ~^             ~~~~~~~~~~
             %ls
54908259.c:30:3: warning: this ‘for’ clause does not guard... [-Wmisleading-indentation]
   for (i = 0; i < employeecount; ++i)
   ^~~
54908259.c:32:5: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the ‘for’
     printf("\n");
     ^~~~~~
54908259.c:37:14: warning: format ‘%i’ expects argument of type ‘int’, but argument 2 has type ‘int *’ [-Wformat=]
     printf("%i\t%s\t%s\n", info[i].id, info[i].gender, info[i].name);
             ~^             ~~~~~~~~~~
             %ls
© www.soinside.com 2019 - 2024. All rights reserved.