Bae*_*lix 1 c arrays sorting string qsort
我有一份工作,我现在已经工作了几个小时,我似乎无法做到这一点.赋值是从一个随机数量的名称(来自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);
}
Run Code Online (Sandbox Code Playgroud)
主要的问题是,当我输出我的代码时,我不能使用char*输入变量,因为它的声明方式.temp []将显示,但不会被qsort排序,因为它未被声明为指针.有任何想法吗?
你不能像那样声明你的输入数组.由于您知道用户需要多少,您可以动态分配数组:
char **input = malloc(num * sizeof(char*));
Run Code Online (Sandbox Code Playgroud)
同样,当你阅读你的字符串时,他们需要去的地方.简单地传递一个未初始化的指针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);
}
Run Code Online (Sandbox Code Playgroud)
[注意,这不会阻止用户溢出'name'缓冲区.我scanf仅用于说明目的]
你似乎传递了错误的数组长度qsort.试试这个:
qsort(input, num, sizeof(char *), stringcmp);
Run Code Online (Sandbox Code Playgroud)
完成后,您需要释放所有名称和数组的内存.
for( i = 0; i < num; i++ ) free(input[i]);
free(input);
Run Code Online (Sandbox Code Playgroud)
你能解释整个代码中的**声明吗?我不确定它们用于什么,虽然我知道stringcmp的功能是一种广泛使用的算法,我不知道它是如何工作的; 我被双重去参考标记所抛弃.
是的,在我使用它的情况下,我告诉C要获得单个字符,我必须取消引用指针两次.索引指针时,它将取消引用.所以我通过请求包含num * sizeof(char*)字节的内存块来分配数组.因为我将指针指定给a char**,编译器知道我指向一个包含char*值的内存块.
如果我要求input[0](这是相同的*input)它应该查看该内存的开头并拉出足够的字节来形成一个char*.当我要求时input[1],它跳过那些字节并拉出形成一个字节的下一串字节char*.等等......同样,当我索引a时char*,我会拔出单个字符.
在您的stringcmp功能中,您有以下情况.您传递了一个void*指针,qsort因此它实际上并不知道存储在数组中的数据值的大小.这就是为什么你必须传递数组长度和单个元素的大小.因此,qsort只需盲目地浏览任意大小的任意长度数组,并触发应该包含数据的内存地址以进行比较.因为qsort不知道什么对他们,除了你所在的数组元素,它只是使用void*.
但是你知道那些指针将是你的两个数组元素的内存地址,而你的数组元素是char*.所以你需要一个地址char*(因此你将指针投射到char**).现在你需要在调用时取消引用这些指针,strcmp()因为该函数需要一个char*(即一个直接指向包含字符串字符的内存的值).这就是你使用*in的原因strcmp(*ia, *ib).
| 归档时间: |
|
| 查看次数: |
13469 次 |
| 最近记录: |