我试着编写一个可以对名称进行排序的代码。所以我试图编写一个程序,但它不能按我的意愿工作。我希望名称按字母顺序排序。我还想根据哪个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);
}
我想您可能需要更新您的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的答案中,很好地提到了其他一些细节。
有几个问题,请参阅我添加的// <<<<
评论:
#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
的返回值。你也不需要演员表,但e1
和e2
必须是const
,因为s1
和s2
是const
。
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对按名称排序的比较函数的答案。
编译并启用更多警告,以帮助您诊断问题:
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