使用指针对C中的结构数组进行排序
Sorting an array of structs in C with pointers
我的 CIS class 有一个编码作业。作业是编写一个程序,该程序将创建一个结构数组,最多可容纳 10 只狗的信息。在程序结束时,您应该按名称或大小对狗数组进行排序。但是我无法编写狗数组的排序代码。
我想知道如何对 dogs 数组进行排序以供以后在 main 函数中使用。
代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Dog{
char name[20];
int weight;
int age;
int ageDogYears;
char size[7];
};
typedef struct Dog DG;
void calc(DG[], int);
void sort(DG[], int);
void display();
int main(){
DG dArray[10];
int x = 0;
char str[80], *i;
FILE *inFile;
inFile = fopen("dogfile.txt", "r");
if (inFile == NULL){
printf("Error opening file");
exit(1);
}
while(fgets(str, 80,inFile) != NULL){
i = strtok(str, ", ");
strcpy(dArray[x].name, i);
puts(dArray[x].name);
i = strtok(NULL, ", ");
dArray[x].weight = atoi(i);
printf("%d\n", dArray[x].weight);
i = strtok(NULL, ", ");
dArray[x].age = atoi(i);
printf("%d\n", dArray[x].age);
x++;
}
calc(dArray, x);
sort(dArray, x);
return 0;
}
void calc(DG dog[], int numDogs){
int y, i, total;
for(i = 0; i < numDogs; ++i){
if(dog[i].weight <= 20){
//sets the dog size to small
strcpy(dog[i].size, "Small");
for(y = 0; y < dog[i].age; ++y){
if(y == 0)
total += 15;
else if(y == 1)
total += 8;
else if(y == 2)
total += 5;
else
total += 4;
}
}
else if(dog[i].weight <= 50){
//sets the dog size to medium
strcpy(dog[i].size, "Medium");
for(y = 0; y < dog[i].age; ++y){
if(y == 0)
total += 14;
else if(y == 1)
total += 9;
else if(y == 2)
total += 7;
else
total += 5;
}
}
else{
//sets the dog size to Large
strcpy(dog[i].size, "Large");
for(y = 0; y < dog[i].age; ++y){
if(y == 0)
total += 12;
else if(y == 1)
total += 9;
else if(y == 2)
total += 8;
else
total += 7;
}
}
dog[i].ageDogYears = total;
total = 0;
}
}
void sort(DG dog[], int numDogs){
int sortType, i, y, temp;
printf("\n wlould you like to sort by name(N) or size(S): ");
scanf("%c", &sortType);
switch(sortType){
case 'N': case 'n':
for(i = 0; i < numDogs; ++i){
for(y = 0; y < (numDogs); ++y){
if(dog[y].weight > dog[y+1].weight){
temp = dog[y];
dog[y] = dog[y + 1];
dog[y + 1] = temp;
}
}
}
break;
default:
if((sortType != 's') && (sortType != 'S'))
printf("\n invalid input! Setting sort type to size.");
//sorting of dog names
}
}
示例输入
Fluffy,23,6
Fido,65,7
Pepper,44,5
Bowser,75,10
Victor,10,2
Sassy,51,1
如有任何帮助,我们将不胜感激!谢谢
在我看来,您的错误在于(尽管我将在下面进行其他评论)将 %c
指定为格式描述符以将指针传递给 int
以进行匹配。您必须传递指向 char
的指针,以使 scanf(3)
到 select 成为放置字符的正确位置。您可能没有得到正确的字符或根本没有字符(这会导致程序中出现未定义的行为)
其他一些问题是当请求按名称排序时(在 n
输入字符上)和其他类似的错误,您正在使用结构的 weight
字段。这包括你在内部循环限制条件中使用 y < (numDogs)
(它必须是 y < (numDogs - 1)
,否则你将比较 y
-esim 与 y+1
-esim 元素(超出数组边界)
此外,由于您对两个排序选项使用相同的算法,我应该在内循环中包含 switch
语句(您在其中进行比较)否则将迫使您复制相同的排序代码两次(对于整体排序算法),如:
for(i = 0; i < numDogs; ++i){
for(y = 0; y < (numDogs - 1); ++y){
int sortResultGreater;
switch (sortType) {
case 'n': case 'N':
sortResultGreater = strcmp(dog[y].name, dog[y+1].name) > 0;
break;
default: { /* this should be done as soon as you know the sorting type, not here inside the loop, of course */
static int not_already_printed = 1;
if (not_already_printed) {
printf("Error, sortType must be [nNsS], defaulting to n\n");
not_already_printed = 0; /* so we don't get here again */
}
} /* scope of not_already_printed finishes here */
/* no break used here to fallback to the next case */
case 's': case 'S':
sortResultGreater = dog[y].weight > dog[y+1].weight;
break;
} /* switch */
if(sortResultGreater){
temp = dog[y];
dog[y] = dog[y + 1];
dog[y + 1] = temp;
}
}
}
我的 CIS class 有一个编码作业。作业是编写一个程序,该程序将创建一个结构数组,最多可容纳 10 只狗的信息。在程序结束时,您应该按名称或大小对狗数组进行排序。但是我无法编写狗数组的排序代码。
我想知道如何对 dogs 数组进行排序以供以后在 main 函数中使用。
代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Dog{
char name[20];
int weight;
int age;
int ageDogYears;
char size[7];
};
typedef struct Dog DG;
void calc(DG[], int);
void sort(DG[], int);
void display();
int main(){
DG dArray[10];
int x = 0;
char str[80], *i;
FILE *inFile;
inFile = fopen("dogfile.txt", "r");
if (inFile == NULL){
printf("Error opening file");
exit(1);
}
while(fgets(str, 80,inFile) != NULL){
i = strtok(str, ", ");
strcpy(dArray[x].name, i);
puts(dArray[x].name);
i = strtok(NULL, ", ");
dArray[x].weight = atoi(i);
printf("%d\n", dArray[x].weight);
i = strtok(NULL, ", ");
dArray[x].age = atoi(i);
printf("%d\n", dArray[x].age);
x++;
}
calc(dArray, x);
sort(dArray, x);
return 0;
}
void calc(DG dog[], int numDogs){
int y, i, total;
for(i = 0; i < numDogs; ++i){
if(dog[i].weight <= 20){
//sets the dog size to small
strcpy(dog[i].size, "Small");
for(y = 0; y < dog[i].age; ++y){
if(y == 0)
total += 15;
else if(y == 1)
total += 8;
else if(y == 2)
total += 5;
else
total += 4;
}
}
else if(dog[i].weight <= 50){
//sets the dog size to medium
strcpy(dog[i].size, "Medium");
for(y = 0; y < dog[i].age; ++y){
if(y == 0)
total += 14;
else if(y == 1)
total += 9;
else if(y == 2)
total += 7;
else
total += 5;
}
}
else{
//sets the dog size to Large
strcpy(dog[i].size, "Large");
for(y = 0; y < dog[i].age; ++y){
if(y == 0)
total += 12;
else if(y == 1)
total += 9;
else if(y == 2)
total += 8;
else
total += 7;
}
}
dog[i].ageDogYears = total;
total = 0;
}
}
void sort(DG dog[], int numDogs){
int sortType, i, y, temp;
printf("\n wlould you like to sort by name(N) or size(S): ");
scanf("%c", &sortType);
switch(sortType){
case 'N': case 'n':
for(i = 0; i < numDogs; ++i){
for(y = 0; y < (numDogs); ++y){
if(dog[y].weight > dog[y+1].weight){
temp = dog[y];
dog[y] = dog[y + 1];
dog[y + 1] = temp;
}
}
}
break;
default:
if((sortType != 's') && (sortType != 'S'))
printf("\n invalid input! Setting sort type to size.");
//sorting of dog names
}
}
示例输入
Fluffy,23,6
Fido,65,7
Pepper,44,5
Bowser,75,10
Victor,10,2
Sassy,51,1
如有任何帮助,我们将不胜感激!谢谢
在我看来,您的错误在于(尽管我将在下面进行其他评论)将 %c
指定为格式描述符以将指针传递给 int
以进行匹配。您必须传递指向 char
的指针,以使 scanf(3)
到 select 成为放置字符的正确位置。您可能没有得到正确的字符或根本没有字符(这会导致程序中出现未定义的行为)
其他一些问题是当请求按名称排序时(在 n
输入字符上)和其他类似的错误,您正在使用结构的 weight
字段。这包括你在内部循环限制条件中使用 y < (numDogs)
(它必须是 y < (numDogs - 1)
,否则你将比较 y
-esim 与 y+1
-esim 元素(超出数组边界)
此外,由于您对两个排序选项使用相同的算法,我应该在内循环中包含 switch
语句(您在其中进行比较)否则将迫使您复制相同的排序代码两次(对于整体排序算法),如:
for(i = 0; i < numDogs; ++i){
for(y = 0; y < (numDogs - 1); ++y){
int sortResultGreater;
switch (sortType) {
case 'n': case 'N':
sortResultGreater = strcmp(dog[y].name, dog[y+1].name) > 0;
break;
default: { /* this should be done as soon as you know the sorting type, not here inside the loop, of course */
static int not_already_printed = 1;
if (not_already_printed) {
printf("Error, sortType must be [nNsS], defaulting to n\n");
not_already_printed = 0; /* so we don't get here again */
}
} /* scope of not_already_printed finishes here */
/* no break used here to fallback to the next case */
case 's': case 'S':
sortResultGreater = dog[y].weight > dog[y+1].weight;
break;
} /* switch */
if(sortResultGreater){
temp = dog[y];
dog[y] = dog[y + 1];
dog[y + 1] = temp;
}
}
}