如何按升序排列结构数组中的结构?
How can I arrange the structs in an array of structs in an ascending order?
如果这听起来令人困惑,我很抱歉,我会尽量说清楚。我有一个结构数组,其中数组存储一个我定义为名片的结构。但是,在将任何新名片添加到数组之前,我必须根据员工 ID 的整数值按升序存储结构。
结构如下:
typedef struct{
int nameCardID;
char personName[20];
char companyName[20];
} NameCard;
因此,我尝试使用关系运算符比较 ID 的值,并按升序将其复制到另一个名为 fakeHolder 的临时数组,最后复制到实际数组。但是,我似乎无法理解为什么在输入我的数据作为 ID 9、7、5 后顺序不对。
这是我的辅助函数:
int addNameCard(NameCard *nc, int *size){
int i = 0;
// Why is this a pointer?
NameCard fakeHolder[10];
char dummy[100];
char *p;
printf("addNameCard():\n");
if(*size == MAX){
printf("The name card holder is full");
// To quit the program
return 0;
}
// Keeps it to Fake Name Card Holder First
printf("Enter nameCardID:\n");
scanf("%d", &fakeHolder->nameCardID);
scanf("%c", &dummy);
printf("Enter personName:\n");
fgets(fakeHolder->personName, 20, stdin);
if(p = strchr(fakeHolder->personName, '\n')){
*p = '[=11=]';
}
printf("Enter companyName:\n");
fgets(fakeHolder->companyName, 20, stdin);
if(p = strchr(fakeHolder->companyName, '\n')){
*p = '[=11=]';
}
// Compare the ID value
for(int j = 0; j < *size; j += 1){
if(fakeHolder->nameCardID == (nc+j)->nameCardID){
printf("The nameCardID has already existed");
}
else if(fakeHolder->nameCardID < (nc+j)->nameCardID){
fakeHolder[(j+1)].nameCardID = (nc+j)->nameCardID;
strcpy(fakeHolder[(j+1)].personName,(nc+j)->personName);
strcpy(fakeHolder[(j+1)].companyName, (nc+j)->companyName);
}
}
*size += 1;
// Transfer to the Actual Name Card Holder
for(int k = 0; k < *size; k += 1){
(nc+k)->nameCardID = fakeHolder[k].nameCardID;
strcpy((nc+k)->personName, fakeHolder[k].personName);
strcpy((nc+k)->companyName, fakeHolder[k].companyName);
}
printf("The name card has been added successfully\n");
return 0;
}
您当前的代码有几个问题,您可以重写它以使其更易于维护和使用。例如,
i
(在 int i = 0;
中)未被使用
scanf("%c", &dummy);
在那里,我假设,删除尾随 \n
- 但是一个 100 个字符的缓冲区用于读取单个字符是......令人惊讶的。有关“整数后的尾随内容”的不同方法的大量讨论,请参阅 scanf() leaves the new line char in the buffer。
- 将
addNameCard
拆分为 2 个函数,一个实际请求 NameCard,另一个将其插入数组,这样可以更好地划分职责,并使您的程序更易于测试。避免将 input/output 与程序逻辑混合。
你问的问题可以通过标准库qsort
函数解决,如下:
#include <stdlib.h>
typedef struct{
int nameCardID;
char personName[20];
char companyName[20];
} NameCard;
void show(NameCard *nc, int n) {
for (int i=0; i<n; i++, nc++) {
printf("%d,%s,%s\n",
nc->nameCardID, nc->personName, nc->companyName);
}
}
// comparison functions to qsort must return int and receive 2 const void * pointers
// they must then return 0 for equal, or <0 / >0 for lower/greater
int compareCardsById(const void *a, const void *b) {
return ((NameCard *)a)->nameCardID - ((NameCard *)b)->nameCardID;
}
int main() {
NameCard nc[10];
nc[0] = (NameCard){1, "bill", "foo"};
nc[1] = (NameCard){3, "joe", "bar"};
nc[2] = (NameCard){2, "ben", "qux"};
show(nc, 3);
// calling the libraries' sort on the array; see "man qsort" for details
qsort(nc, 3, sizeof(NameCard), compareCardsById);
show(nc, 3);
return 0;
}
如果这听起来令人困惑,我很抱歉,我会尽量说清楚。我有一个结构数组,其中数组存储一个我定义为名片的结构。但是,在将任何新名片添加到数组之前,我必须根据员工 ID 的整数值按升序存储结构。
结构如下:
typedef struct{
int nameCardID;
char personName[20];
char companyName[20];
} NameCard;
因此,我尝试使用关系运算符比较 ID 的值,并按升序将其复制到另一个名为 fakeHolder 的临时数组,最后复制到实际数组。但是,我似乎无法理解为什么在输入我的数据作为 ID 9、7、5 后顺序不对。
这是我的辅助函数:
int addNameCard(NameCard *nc, int *size){
int i = 0;
// Why is this a pointer?
NameCard fakeHolder[10];
char dummy[100];
char *p;
printf("addNameCard():\n");
if(*size == MAX){
printf("The name card holder is full");
// To quit the program
return 0;
}
// Keeps it to Fake Name Card Holder First
printf("Enter nameCardID:\n");
scanf("%d", &fakeHolder->nameCardID);
scanf("%c", &dummy);
printf("Enter personName:\n");
fgets(fakeHolder->personName, 20, stdin);
if(p = strchr(fakeHolder->personName, '\n')){
*p = '[=11=]';
}
printf("Enter companyName:\n");
fgets(fakeHolder->companyName, 20, stdin);
if(p = strchr(fakeHolder->companyName, '\n')){
*p = '[=11=]';
}
// Compare the ID value
for(int j = 0; j < *size; j += 1){
if(fakeHolder->nameCardID == (nc+j)->nameCardID){
printf("The nameCardID has already existed");
}
else if(fakeHolder->nameCardID < (nc+j)->nameCardID){
fakeHolder[(j+1)].nameCardID = (nc+j)->nameCardID;
strcpy(fakeHolder[(j+1)].personName,(nc+j)->personName);
strcpy(fakeHolder[(j+1)].companyName, (nc+j)->companyName);
}
}
*size += 1;
// Transfer to the Actual Name Card Holder
for(int k = 0; k < *size; k += 1){
(nc+k)->nameCardID = fakeHolder[k].nameCardID;
strcpy((nc+k)->personName, fakeHolder[k].personName);
strcpy((nc+k)->companyName, fakeHolder[k].companyName);
}
printf("The name card has been added successfully\n");
return 0;
}
您当前的代码有几个问题,您可以重写它以使其更易于维护和使用。例如,
i
(在int i = 0;
中)未被使用scanf("%c", &dummy);
在那里,我假设,删除尾随\n
- 但是一个 100 个字符的缓冲区用于读取单个字符是......令人惊讶的。有关“整数后的尾随内容”的不同方法的大量讨论,请参阅 scanf() leaves the new line char in the buffer。- 将
addNameCard
拆分为 2 个函数,一个实际请求 NameCard,另一个将其插入数组,这样可以更好地划分职责,并使您的程序更易于测试。避免将 input/output 与程序逻辑混合。
你问的问题可以通过标准库qsort
函数解决,如下:
#include <stdlib.h>
typedef struct{
int nameCardID;
char personName[20];
char companyName[20];
} NameCard;
void show(NameCard *nc, int n) {
for (int i=0; i<n; i++, nc++) {
printf("%d,%s,%s\n",
nc->nameCardID, nc->personName, nc->companyName);
}
}
// comparison functions to qsort must return int and receive 2 const void * pointers
// they must then return 0 for equal, or <0 / >0 for lower/greater
int compareCardsById(const void *a, const void *b) {
return ((NameCard *)a)->nameCardID - ((NameCard *)b)->nameCardID;
}
int main() {
NameCard nc[10];
nc[0] = (NameCard){1, "bill", "foo"};
nc[1] = (NameCard){3, "joe", "bar"};
nc[2] = (NameCard){2, "ben", "qux"};
show(nc, 3);
// calling the libraries' sort on the array; see "man qsort" for details
qsort(nc, 3, sizeof(NameCard), compareCardsById);
show(nc, 3);
return 0;
}