如何在 C 中对 argv 的元素进行排序?
Posted
技术标签:
【中文标题】如何在 C 中对 argv 的元素进行排序?【英文标题】:How do I sort the elements of argv in C? 【发布时间】:2011-04-12 01:06:08 【问题描述】:我正在尝试按字母顺序对 argv 的元素进行排序。
以下代码行给我带来了问题:
qsort(argv[optind], argc - optind, sizeof(argv[optind]), sort);
具体来说,最后一个参数给我带来了麻烦,比较函数,如下所示:
int
sort(const void *a, const void * b)
return(strcmp( (char*)a, (char*)b ));
目前,它编译得很好,但是当我运行它时,我最终遇到了分段错误。
【问题讨论】:
如果我没记错的话,修改argv
数组会导致未定义的行为。你可能会向给你这个家庭作业的人提到这一点,如果你能在标准中找到引文,甚至可能会获得额外的学分(留给读者作为练习)。
是的,某些平台似乎可以从一些有趣的技巧中受益,因此未定义的行为似乎是合理的。另一方面,手册页示例与数组一起使用的事实可能表明并非如此。或者我们在手册页中发现了一个错误。 :-)
嗯,实际上,任务不是对 argv 数组进行排序。基本上,整个程序应该计算指定文件的字符数、单词数和行数并打印出结果,但按字母顺序排列。我的程序目前可以正确计算所有内容,但我需要找到一种方法使其按字母顺序打印出来,所以我认为对 argv 数组进行排序是一个好主意,因为所有文件名都在那里。无论如何,在按照你们的建议进行一些调整后,我可以将它打印到第一个文件及其计数的位置,但是......继续下面
然后我得到一个分段错误。当我得到分段错误时,我使用 printf 语句检查当前文件名是什么,它表明它是 LANG=en_US.UTF-8 ,我不知道那是什么......为了更清楚,我在命令行中指定文件 test1.txt hello.txt abcd.txt。并且使用 qsort(),我可以将它打印到输出 abcd.txt 的位置(按字母顺序排列)及其计数。但后来我得到一个分段错误并检查正在传递的文件名,我看到它的 LANG
...从上面继续,我看到它的 LANG=en_US.UTF-8 如果我不尝试对其进行排序,它可以完美运行,但会按照输入的顺序打印出来命令行。
【参考方案1】:
第一个参数应该是argv+optind
,因为这是要排序的序列中第一个元素的地址。
【讨论】:
真的吗?请记住,argv 是一个数组或字符串指针,因此 argv[optind] 将指向第一个字符串。 它需要指向列表的开头,而不是在要排序的事物中。&argv[optind]
可能是一种更直观的方式来看待这一点,这取决于人们的思维方式。
确实如此,然后排序函数需要比较char **
。
是的。这两件事都包含在 linux.die.net/man/3/qsort 上的 qsort()
手册页中。【参考方案2】:
qsort(3)
的手册页包含一个示例,它完全符合您的要求。它还解释了原因:
http://linux.die.net/man/3/qsort
总结:您在qsort()
第一个参数上缺少一级引用,并且在sort()
函数中缺少一级取消引用。
【讨论】:
【参考方案3】:问题出在 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);
【讨论】:
那么这是否意味着没有办法对argv的元素进行排序? 这个答案不正确。argv
是一个指针数组。如果这些指针指向的字符串数据恰好是您的答案中的结构,那么它纯粹是 您 正在使用的操作系统/编译器的实现细节。 argv
不应该被这样访问。【参考方案4】:
这是我对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 一二三四五六七 我:1 ==>'五' i: 2 ==> '四' i: 3 ==> '一' i: 4 ==> '七' 我:5 ==>'六' 我:6 ==>'三' 我:7 ==>'两个'【讨论】:
以上是关于如何在 C 中对 argv 的元素进行排序?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 D3 中对绑定到不同数据(与 forcesimulatoin 一起使用)的元素进行分组,以便对它们进行排序