2009-12-30 31 views
0

什麼是解析逗號分隔列表的最簡單方法,每個記號之間可以有零個元素。 CString對象可能看起來像如何解析','分離的字符串使用c?

1, 3, 4, 5, 6, 7, 8, .... 

但也可能看起來像

, , , , , , , , , ... 

我已經試過類似:

char *original = "1, 3, 4, 5, 6, 7, 8, ...." 
char *tok = strtok(original," ,") 
while(tok!=NULL){ 
    while(*tok!='\0'){ 
     //dostuff 
     tok++; 
    } 
tok=strtok(NULL," ,"); 
} 

這顯然只適用,如果有逗號的元素之間,例如我注意到,如果沒有元素,第一個項目列表將被跳過。

我試過其他解決方案,如strchr(),但這變得非常難看,我認爲有一個更簡單的方法。

感謝

更新:

一些測試我注意到,標化的「」似乎工作,在所有的情況下,除非第一項失蹤後。所以我把它作爲一個特例來解決。

char *original = "1, 3, 4, 5, 6, 7, 8, ...." 
if(*original==',') 
    //dostuff  
char *tok = strtok(original,",") 
while(tok!=NULL){ 
    while(*tok!='\0'){ 
     //dostuff 
     tok++; 
    } 
tok=strtok(NULL,","); 
} 

感謝您的輸入和您的幫助。 (也許我應該發佈前給予該更仔細的思考。)

+3

爲什麼不使用任何庫自己編寫整個東西? – 2009-12-30 04:27:57

回答

0
strtok cannot cannot distinguish between `,` and `,,`. 
+1

嗨,謝謝你的回覆,逗號後面還有一個空格,所以如果我只是使用「,」作爲分隔符,它仍然會跳過第一個元素。 – monkeyking 2009-12-30 04:27:02

3

你可能要考慮的非標準strsep,其目的是爲strtok更換允許空字段的解析。另請參閱Finding Tokens in a String上的glibc手冊章節。它在許多系統(各種BSD,Linux,Mac OS X)上都可用,但不是標準化的,所以我相信它可能不在Windows或Solaris上。

+0

布賴恩,我不認爲這是一個非常好的主意,建議對新手使用非標準函數 – 2009-12-30 04:31:29

+0

我認爲指出非標準函數可以滿足他們的需求是合理的,只要你包含一個警告可能無法在所有系統上使用。只要我提供足夠的信息來說明可能存在可移植性問題,我通常會將問題留給提問者來確定我的答案是否足夠。你認爲我應該在我的回答開始時提出警告,而不是結束? – 2009-12-30 04:38:56

+0

@布萊恩,也許讓它更加明顯?即就像說「警告,這會讓你的代碼不可移植」。另外,由於它沒有被標準化,所以你不能確定它會在你提到的所有平臺上。你假定一個特定的環境/編譯器/庫,但實際上用戶可以有不同的東西。標準功能和符合標準的編譯器不是這種情況。 – 2009-12-30 04:41:54

0

簡單的for循環怎麼樣?

for (int begin = 0; original[begin];) { 
    int end = begin; 
    while (original[end] && original[end] != ',') 
    ++end; 

    // do something with original[begin] through original[end-1] 

    begin = end; 
} 
2

如果你需要做的就是忽略空「令牌」,您可以使用strspn功能來檢測空白,隻字符串。下面是一個例子:

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


/* Is the given string whitespace only? 
*/ 
int iswhitespace(char* s) 
{ 
    return (strspn(s, " \t") == strlen(s)); 
} 


int main() 
{ 
    char line[] = "1, , 3, 4, 5, 6"; 
    char sep[] = ","; 
    char* tok; 

    tok = strtok(line, sep); 

    while (tok) 
    { 
     if (iswhitespace(tok)) 
      printf("empty token\n"); 
     else 
      printf("new token: %s\n", tok); 

     tok = strtok(0, sep); 
    } 

    return 0; 
} 

這裏的關鍵思想是僅在逗號上標記化,而不是「」,它跳過第一個元素。空白然後可以分開處理。

當然這仍然留下strtok將跳過連續逗號的跨度的事實。如果這對你不好,你不能使用strtok,而必須使用另一種解決方案。

+1

+1提交時,我正在鍵入我的這個答案的版本... – mrkj 2009-12-30 04:41:52