2013-03-26 72 views
-1

我需要在C執行字符串上一長串的各種功能處理C中char *的列表?

char *list1[] = {"one","two","three", "four","five","six"}; 

起初,我想實現簡單的汽車/ CDR功能,但它已經有一段時間,我忘記的最好方式在C.cdr中管理char * []的列表應該返回char *列表的其餘部分到一個新的malloc'ed數組中。就我而言,它是「兩」,「三」,「四」,「五」,「六」。名單的大小是未知的複雜這一點。也許,我應該使用列表長度的結構?

char **cdr(char *aList[]) { 
    /* 
    malloc space for n-1 char* 
    */ 
    return aList; // Return everything to test 
} 

我有其他的功能,比方說,例如,用連續的兩個元音或單詞超過10個字符返回的所有單詞列表。我永遠不想改變字符串(即它們是不可變的)。我將在cdr這樣的函數中使用malloc來存儲內存,所以我需要跟蹤這些內容,並將結果傳遞給其他函數。無論如何,如果有人能讓我開始,它將不勝感激。謝謝。

char *list1[] = {"one","two","three", "four","five","six"}; // Short list 

char **cdr(char *aList[]) { 
    /* 
    malloc space for n-1 char* 
    */ 
    return aList; // Return everything to test 
} 

char *car(char *aList[]) { 
    return aList[0]; 
} 

int main() { 
    const char *first; 
    char *rest[]; 

    int len = sizeof(list1)/sizeof(char*); 
    printf("list1 len=%d\n", len); 

    first = car(list1); 
    rest = cdr(list1); 

    printf("%s\n", first); 
    len = sizeof(rest)/sizeof(char*); 
    printf("rest len=%d\n", len); 

    return 0; 
} 
+0

「也許,我應該使用一個具有列表長度的結構?」 - 也許你應該使用一個缺點清單。否則,你不應該使用「car」和「cdr」的名字。 – 2013-03-27 00:45:22

+2

「sizeof(rest)/ sizeof(char *);」 ---錯錯錯了那麼錯。我們每天在SO上得到大約2-3個問題,誤解了'sizeof'。這是一個**編譯時**構造,它只知道變量的大小,而不知道它們的內容。 – 2013-03-27 00:47:49

+0

我希望你不要每個人都回答「錯誤的錯誤是錯誤的」不是每個人都像C一樣開始他們的職業生涯,你可能會阻止人們學習C.對我來說已經過了十年了,所以我已經做了任何嚴肅的事情工作,所以我很生鏽。我用Java軟了。 :-)至於car/cdr,這是一種毫無意義的建議。汽車是第一個結果,其餘的是cdr。簡而言之,下一次只需指出FAQ。謝謝。 – h4labs 2013-03-29 20:27:03

回答

2

名單大小未知不是很「複雜」,因爲「使它變得不可能」。如果您不想傳遞明確的長度,則需要使用NULL值作爲終止符。

int length(const char* strings[]) { 
    int rv = 0; 
    while(strings[rv]) ++rv; 
    return rv; 
} 

int main(int argc, char *argv[]) { 
    printf("Note that this technique is also used in argv: %p\n", argv[argc]); 

    const *list[] = { "+", "42", "30", NULL }; 
    printf("Length: %d\n", length(list)); 

    return 0; 
} 

使用這樣的長度()在你的其他功能,你應該再能知道的內存來分配相應的金額。 (請記住,您需要爲NULL指定一個額外指針的空間!)

2

通常,您尋找的列表不是作爲數組實現,而是作爲鏈接列表實現。他們首次實施的方式甚至是操作被稱爲「汽車」和「cdr」的原因(參見:http://en.wikipedia.org/wiki/CAR_and_CDR)。

以這種方式實現的列表只包含包含兩個指針的元素。因此,對於你的例子這樣一份清單是這樣的:

+-----+-----+ +-----+-----+ +-----+-----+   +-----+-----+ 
| car | cdr | -> | car | cdr | -> | car | cdr | -> .... | car | cdr | -> NIL 
+-----+-----+ +-----+-----+ +-----+-----+   +-----+-----+ 
    |     |    |      | 
    v     v    v      v 
"one"    "two"   "three"    "six" 

爲了更好地實現用C你寧願使用結構類似的列表的元素以下相同:

struct _Element { 
    struct _Element *cdr; 
    void *car; 
}; 

如果你仍然想用數組方法,而不是最好看看「svk」的帖子。使用NULL終止的數組而不是單獨記錄長度可能是您建議的版本的有趣替代方案。

0

C中的所有mallocing和freeing都是浪費和容易出錯的。爲什麼不只是返回實際的字符串?

char * car (char ** list) { 
    return list[0]; 
} 

char ** cdr (char ** list) { 
    return list + 1; 
} 
+0

cdr()/ rest()只是一個例子。例如,我可能想將列表拆分爲4個較小的列表,或返回以「他」開頭的所有單詞。 – h4labs 2013-03-27 19:13:00