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'