在C中对字符串数组排序

在C中对字符串数组排序,c,arrays,string,sorting,qsort,C,Arrays,String,Sorting,Qsort,我有一个作业,我已经做了几个小时了,但我似乎做得不太对。任务是从stdin中随机抽取一些名称,对它们进行排序,然后按字母顺序输出它们。我在网上找不到任何专门处理这种排序的网站,也没有幸尝试在我的代码中实现qsort() #include <stdio.h> #include <string.h> #include <stdlib.h> int stringcmp(const void *a, const void *b) { const c

我有一个作业,我已经做了几个小时了,但我似乎做得不太对。任务是从stdin中随机抽取一些名称,对它们进行排序,然后按字母顺序输出它们。我在网上找不到任何专门处理这种排序的网站,也没有幸尝试在我的代码中实现qsort()

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


int stringcmp(const void *a, const void *b) 
{ 
    const char **ia = (const char **)a;
    const char **ib = (const char **)b;
    return strcmp(*ia, *ib);
} 

void main(int argc, char *argv[])
{
     char *input[] = {" "};
     char temp[20][20];
     int i = 0;
     int num = 0;
     int place = 0;
     int stringlen = sizeof(temp) / sizeof(char);


          printf("How many names would you like to enter? ");
          scanf("%d", &num);

          while (place < num)
          {
                printf("Please input a name(first only): ");
                scanf("%s", input[place]);
                printf("The name you entered is: ");
                printf("%s\n", input[place]);

                place++;
          }
          //qsort(temp, stringlen, sizeof(char *), stringcmp);      <-- just an idea I was messing with
          qsort(input, stringlen, sizeof(char *), stringcmp);

          printf("Names:\n");

          for(i=0; i<place; i++)
               printf("%s\n", input[i]);



          system("PAUSE");
          return(EXIT_SUCCESS);

}
#包括
#包括
#包括
int stringcmp(常数无效*a,常数无效*b)
{ 
常量字符**ia=(常量字符**)a;
常量字符**ib=(常量字符**)b;
返回strcmp(*ia,*ib);
} 
void main(int argc,char*argv[])
{
字符*输入[]={”“};
字符温度[20][20];
int i=0;
int num=0;
int place=0;
int stringlen=sizeof(temp)/sizeof(char);
printf(“您想输入多少个姓名?”);
scanf(“%d”和&num);
while(位置//qsort(temp、stringlen、sizeof(char*)、stringcmp);修复程序的一种快速方法是将
input
声明为指针数组,如下所示:

char *input[20];
scanf("%19s", tmp[place]);
input[place] = tmp[place];
当您在中读取名称时,使用
tmp[place]
作为缓冲区,并将指针存储到
input
,如下所示:

char *input[20];
scanf("%19s", tmp[place]);
input[place] = tmp[place];
现在对
输入进行排序应该可以正常工作了


这有一个限制,最多20行20个字符。如果您在类中了解了
malloc
,您应该能够通过动态分配字符串和字符串数组来解决此问题。

解决程序问题的一个快速方法是将
输入
声明为指针数组,如下所示:

char *input[20];
scanf("%19s", tmp[place]);
input[place] = tmp[place];
当您在中读取名称时,使用
tmp[place]
作为缓冲区,并将指针存储到
input
,如下所示:

char *input[20];
scanf("%19s", tmp[place]);
input[place] = tmp[place];
现在对
输入进行排序应该可以正常工作了


这有一个限制,最多20行20个字符。如果您在类中了解了
malloc
,您应该能够通过动态分配字符串和字符串数组来解决此问题。

您不能这样声明输入数组。因为您知道用户需要多少,所以可以动态分配他说:

char **input = malloc(num * sizeof(char*));
同样,当您读入字符串时,它们需要放在某个地方。简单地将未初始化的指针传递到
scanf
是不合适的。我建议您定义名称的最大长度,并使用临时缓冲区来读取它:

const size_t MAX_NAME = 50;
char name[MAX_NAME];

...

for( i = 0; i < num; i++ )
{
    printf("Please input a name(first only): ");
    scanf("%s", name);
    input[i] = strdup(name);
}
完成后,需要释放所有名称和数组的内存

for( i = 0; i < num; i++ ) free(input[i]);
free(input);
for(i=0;i
你能解释一下吗 代码中的**声明?我不确定它们是什么 用于,尽管我知道stringcmp的函数是一个广泛使用的函数 算法,我不知道它是怎么工作的,我被双重的 去参考标记

是的,在我使用它的情况下,我告诉C为了得到一个字符,我必须对指针取消引用两次。当你对指针进行索引时,它就是取消引用。所以我通过请求一个包含
num*sizeof(char*)的内存块来分配一个数组
bytes。由于我将该指针分配给了
char**
,编译器知道我指向的是包含
char*
值的内存块

如果我请求
输入[0]
(这与
*输入
)相同,它应该查看该内存的最开始,并提取足够的字节以形成
字符*
。当我请求
输入[1]
,它跳过这些字节,然后取出下一组字节,这些字节形成一个
char*
。等等。同样,当我为
char*
编制索引时,我取出的是单个字符

stringcmp
函数中,您有以下情况。您传递了指向
qsort
void*
指针,因此它实际上不知道存储在数组中的数据值的大小。这就是为什么您必须同时传递数组长度和单个元素的大小。因此
qsort
只是盲目地通过ugh这个任意长度的数组包含任意大小的值,并触发应该包含数据以进行比较的内存地址。因为
qsort
除了知道数组元素的位置之外,不知道其他任何关于数组元素的信息,所以它只使用
void*


但是您知道这些指针将是两个数组元素的内存地址,并且数组元素是
char*
。因此您需要
char*
的地址(因此您将指针强制转换为
char**
)。现在您需要在调用
strcmp()时取消对这些指针的引用
因为该函数需要一个
char*
(即直接指向包含字符串的内存的值)。这就是为什么在
strcmp(*ia,*ib)中使用
*

您不能这样声明您的输入数组。因为您知道用户需要多少,所以可以动态分配数组:

char **input = malloc(num * sizeof(char*));
同样,当您读入字符串时,它们需要放在某个地方。简单地将未初始化的指针传递到
scanf
是不合适的。我建议您定义名称的最大长度,并使用临时缓冲区来读取它:

const size_t MAX_NAME = 50;
char name[MAX_NAME];

...

for( i = 0; i < num; i++ )
{
    printf("Please input a name(first only): ");
    scanf("%s", name);
    input[i] = strdup(name);
}
完成后,需要释放所有名称和数组的内存

for( i = 0; i < num; i++ ) free(input[i]);
free(input);
for(i=0;i
你能解释一下吗 代码中的**声明?我不确定它们是什么 用于,尽管我知道stringcmp的函数是一个广泛使用的函数 算法,我不知道它是怎么工作的,我被双重的 去参考标记

是的,在我使用它的情况下,我告诉C