使用指针按字母顺序对字符串数组进行排序
Sorting an array of strings in an alphabetical order using pointers
我有一个项目,我必须创建一个程序,让用户以任何顺序输入名称。然后程序按字母顺序显示名称。此外,所有这些都必须使用指针来完成。现在我对该程序的尝试提示用户输入名称并显示它们,但由于某种原因我无法对其进行排序。有人可以帮我吗?
这是我对该程序的尝试:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main() {
int list;
char *names[20];
char str[20];
printf("Enter the number of names: ");
scanf("%d", &list);
fflush(stdin);
for (int i = 0; i < list; i++) {
printf("Enter name %d: ", i + 1);
// gets(str);
scanf("%[^\t\n]s", str);
fflush(stdin);
names[i] = (char *)malloc(strlen(str) + 1);
strcpy(names[i], str);
}
void sortNames();
for (int i = 0; i < 5; i++)
printf("%s\n", names[i]);
return 0;
}
void sortNames(char **name, int *n) {
int i, j;
for (j = 0; j < *n - 1; j++) {
for (i = 0; i < *n - 1; i++) {
if (compareStr(name[i], name[i + 1]) > 0) {
char *t = name[i];
name[i] = name[i + 1];
name[i + 1] = t;
}
}
}
}
int compareStr(char *str1, char *str2) {
while (*str1 == *str2) {
if (*str1 == '[=10=]' || *str2 == '[=10=]')
break;
str1++;
str2++;
}
if (*str1 == '[=10=]' && *str2 == '[=10=]')
return 0;
else
return -1;
}
只关注排序的问题,最主要的是你从来没有调用过你后面定义的排序函数。行
void sortNames();
仅用于 声明 具有标识符 sortNames
的函数,该函数接受任意数量的任意类型的参数(可能不是您想做的)。我建议将此行修改为
sortNames(names, list); // Not &list because I'm about to suggest not taking it as a pointer
然后对于 sortNames
函数本身,我不是很清楚为什么你把要排序的数组的长度作为指针而不是只传递 int
本身。我建议将此函数修改为
void sortNames(char **name, int n) {
int i, j;
for (j = 0; j < n - 1; j++) {
for (i = 0; i < n - 1; i++) {
if (compareStr(name[i], name[i + 1]) > 0) {
char *t = name[i];
name[i] = name[i + 1];
name[i + 1] = t;
}
}
}
}
目前的一个问题是表达式 compareStr(name[i], name[i + 1]) > 0
始终为假。这是因为 compareStr
只会 returns 0 或 -1。您可以通过重写 compareStr
来解决此问题,以正确处理 *str1 > *str2
的情况。一种可能的方法是
int compareStr(char *str1, char *str2) {
if (*str1 == '[=13=]' && *str2 == '[=13=]') {
return 0;
} else if (*str1 > *str2) {
return 1;
} else if (*str1 < *str2) {
return -1;
}
return compareStr(str1 + 1, str2 + 1);
}
虽然如果你写这篇文章是为了学习,我建议你尝试修改你当前的迭代解决方案,而不是仅仅复制和粘贴这个版本。
最后,因为您想在定义它们之前使用这些函数,所以您应该在使用它们之前移动它们的定义(即有 compareStr
,然后 sortNames
和然后 main
) 或在文件开头为这些函数提供前向声明,即 add
void sortNames(char **name, int n);
int compareStr(char *str1, char *str2);
高于您的 main
。
正如其他人所指出的,您可能希望避免 fflush(stdin)
作为其未定义的行为,我建议不要 casting the result of malloc
。
这里的问题是函数 compareStr
永远不会 return 一个大于 0 的值。它只是告诉你这两个字符串是否相似。
为了排序,您需要添加一个额外的逻辑如下:
int compareStr(char *str1, char *str2) {
while (*str1 == *str2) {
if (*str1 == '[=10=]' || *str2 == '[=10=]')
break;
str1++;
str2++;
}
if (*str1 == '[=10=]' && *str2 == '[=10=]'){
return 0;
}
else if(*str1 > *str2){
return 1;
}else{
return -1;
}
}
除此之外,您必须调用函数 sortNames
作为 sortNames(names, &list) 并确保函数定义以正确的顺序编写或使用函数声明。
我有一个项目,我必须创建一个程序,让用户以任何顺序输入名称。然后程序按字母顺序显示名称。此外,所有这些都必须使用指针来完成。现在我对该程序的尝试提示用户输入名称并显示它们,但由于某种原因我无法对其进行排序。有人可以帮我吗?
这是我对该程序的尝试:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main() {
int list;
char *names[20];
char str[20];
printf("Enter the number of names: ");
scanf("%d", &list);
fflush(stdin);
for (int i = 0; i < list; i++) {
printf("Enter name %d: ", i + 1);
// gets(str);
scanf("%[^\t\n]s", str);
fflush(stdin);
names[i] = (char *)malloc(strlen(str) + 1);
strcpy(names[i], str);
}
void sortNames();
for (int i = 0; i < 5; i++)
printf("%s\n", names[i]);
return 0;
}
void sortNames(char **name, int *n) {
int i, j;
for (j = 0; j < *n - 1; j++) {
for (i = 0; i < *n - 1; i++) {
if (compareStr(name[i], name[i + 1]) > 0) {
char *t = name[i];
name[i] = name[i + 1];
name[i + 1] = t;
}
}
}
}
int compareStr(char *str1, char *str2) {
while (*str1 == *str2) {
if (*str1 == '[=10=]' || *str2 == '[=10=]')
break;
str1++;
str2++;
}
if (*str1 == '[=10=]' && *str2 == '[=10=]')
return 0;
else
return -1;
}
只关注排序的问题,最主要的是你从来没有调用过你后面定义的排序函数。行
void sortNames();
仅用于 声明 具有标识符 sortNames
的函数,该函数接受任意数量的任意类型的参数(可能不是您想做的)。我建议将此行修改为
sortNames(names, list); // Not &list because I'm about to suggest not taking it as a pointer
然后对于 sortNames
函数本身,我不是很清楚为什么你把要排序的数组的长度作为指针而不是只传递 int
本身。我建议将此函数修改为
void sortNames(char **name, int n) {
int i, j;
for (j = 0; j < n - 1; j++) {
for (i = 0; i < n - 1; i++) {
if (compareStr(name[i], name[i + 1]) > 0) {
char *t = name[i];
name[i] = name[i + 1];
name[i + 1] = t;
}
}
}
}
目前的一个问题是表达式 compareStr(name[i], name[i + 1]) > 0
始终为假。这是因为 compareStr
只会 returns 0 或 -1。您可以通过重写 compareStr
来解决此问题,以正确处理 *str1 > *str2
的情况。一种可能的方法是
int compareStr(char *str1, char *str2) {
if (*str1 == '[=13=]' && *str2 == '[=13=]') {
return 0;
} else if (*str1 > *str2) {
return 1;
} else if (*str1 < *str2) {
return -1;
}
return compareStr(str1 + 1, str2 + 1);
}
虽然如果你写这篇文章是为了学习,我建议你尝试修改你当前的迭代解决方案,而不是仅仅复制和粘贴这个版本。
最后,因为您想在定义它们之前使用这些函数,所以您应该在使用它们之前移动它们的定义(即有 compareStr
,然后 sortNames
和然后 main
) 或在文件开头为这些函数提供前向声明,即 add
void sortNames(char **name, int n);
int compareStr(char *str1, char *str2);
高于您的 main
。
正如其他人所指出的,您可能希望避免 fflush(stdin)
作为其未定义的行为,我建议不要 casting the result of malloc
。
这里的问题是函数 compareStr
永远不会 return 一个大于 0 的值。它只是告诉你这两个字符串是否相似。
为了排序,您需要添加一个额外的逻辑如下:
int compareStr(char *str1, char *str2) {
while (*str1 == *str2) {
if (*str1 == '[=10=]' || *str2 == '[=10=]')
break;
str1++;
str2++;
}
if (*str1 == '[=10=]' && *str2 == '[=10=]'){
return 0;
}
else if(*str1 > *str2){
return 1;
}else{
return -1;
}
}
除此之外,您必须调用函数 sortNames
作为 sortNames(names, &list) 并确保函数定义以正确的顺序编写或使用函数声明。