2010-09-14 44 views
0

我想按字母顺序排序argv的元素。如何排列C中argv的元素?

下面的代码行给我的问题:

qsort(argv[optind], argc - optind, sizeof(argv[optind]), sort); 

具体而言,最后一个参数是给我麻烦,比较功能,这是如下:

int 
sort(const void *a, const void * b) 
{  
    return(strcmp((char*)a, (char*)b)); 
} 

目前,它编译得很好,但是当我运行它时,我最终得到了分段错误。

+1

的运行示例如果我没有记错,修改不确定的行为'argv'阵列结果。你可能会提及谁给了你这个家庭作业,如果你能找到标准中的引文(甚至可以作为读者的练习),甚至可以获得额外的功劳。 – 2010-09-14 12:58:26

+0

是的,好像某些平台可以从使用有趣的技巧中受益,所以未定义的行为似乎是合理的。另一方面,手册页示例与数组一起玩的事实可能表明了其他情况。或者我们发现自己在手册页中有一个错误。 :-) – clacke 2010-09-14 13:43:58

+0

实际上,这个赋值不是为了对argv数组进行排序。基本上,整个程序应计算指定文件的字符数,字数和行数,并按字母顺序打印出结果。我的程序目前正确计数一切,但我需要找到一种方法使它按字母顺序打印出来,所以我认为排序argv数组将是一个好主意,因为那里的所有文件名都是这样。 无论如何,经过你们建议的一些调整之后,我可以将它打印到第一个文件和它的计数的位置,但是...继续低于 – DemonicImpact 2010-09-14 18:00:09

回答

3

第一个参数应该是argv+optind,因为这是要排序序列中第一个元素的地址。

+0

真的吗?请记住,argv是一个数组或字符串指针,所以argv [optind]将指向第一个字符串。 – Sjoerd 2010-09-14 08:16:40

+0

它需要指向列表的开始,而不是内部要排序的内容之一。 '&argv [optind]'可能是一种更直观的方式来看待这种情况,这取决于头脑的工作方式。 – clacke 2010-09-14 08:38:29

+1

确实,然后sort函数需要比较'char **'。 – Sjoerd 2010-09-14 08:45:33

-1

问题在于argv数组的结构。

它的结构是这样

program\0arg1\0argument2\0a3\0\0 

的qsort函数假定所有的元素都是相同的尺寸,但在这种情况下,他们都没有。您指定的尺寸为argv[optind],但并非所有元素都是该尺寸。

编辑: 我错了,你不会将字符串长度传递给qsort,而是传递指针的长度。所以argv包含一个指针数组。目标是对指针进行排序。

这意味着您将指针数组传递给qsort,并且该排序函数应该指向一个指针。像这样:

int 
sort(const void *a, const void * b) 
{ 
    return(strcmp(*(char**)a, *(char**)b)); 
} 

qsort(argv+optind, argc - optind, sizeof(argv[optind]), sort); 
+0

那么这是否意味着无法排序argv的元素? – DemonicImpact 2010-09-14 08:24:31

+0

这个答案是不正确的。 'argv'是一个指针数组。如果这些指针所指向的字符串数据碰巧是在您的答案中构造的,那么它纯粹是您正在使用的操作系统/编译器**的实现细节。不应该像这样访问'argv'。 – 2010-09-14 12:56:48

3

qsort(3)的手册页包含一个例子,它正是你想要的。这也解释了为什么:

http://linux.die.net/man/3/qsort

摘要:你缺少引用在qsort()第一个参数的一个级别,而缺少sort()函数内提领的一个水平。

0

这是我在整理argv

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

int mycomp(const void *a, const void *b) { 
    /* function code removed to prevent homework copy/paste */ 
} 

int main(int argc, char **argv) { 
    int i; 
    qsort(argv + 1, argc - 1, sizeof *argv, mycomp); 
    for (i = 1; i < argc; i++) printf("i: %d ==> '%s'\n", i, argv[i]); 
    return 0; 
} 

尝试与程序

 
$ ./a.out one two three four five six seven 
i: 1 ==> 'five' 
i: 2 ==> 'four' 
i: 3 ==> 'one' 
i: 4 ==> 'seven' 
i: 5 ==> 'six' 
i: 6 ==> 'three' 
i: 7 ==> 'two'