2009-11-13 73 views
1

這是對我的previous question的後續處理。我成功實現了檢查虛擬字符的算法。下一個問題來自迭代字符串中的所有字符。我這樣做,像這樣:用模糊字符對字符串/ strlen進行迭代

int main() 
{ 
    char* str = "Hej du kalleåäö"; 
    printf("length of str: %d", strlen(str)); 

    for (int i = 0; i < strlen(str); i++) 
    { 
     printf("%s ", to_morse(str[i])); 
    } 
    putchar('\n'); 
    return 0; 
} 

的問題是,由於umlauted字符,它打印18,也使得to_morse功能失效(忽略這些字符)。 toMorse方法接受一個無符號字符作爲參數。解決這個問題的最好方法是什麼?我知道我可以在這裏檢查變音符字符而不是letterNr函數,但我不知道這是否是一個漂亮/合理的解決方案。

+0

您是否嘗試過在該回復中描述的解決方案到你以前的問題? http://stackoverflow.com/questions/1725124/accented-umlauted-characters-in-c/1725169#1725169 – 2009-11-13 19:38:18

+1

@Carl Smotricz是對的:圖書館是你的朋友在這裏。 UTF-8很聰明,這意味着它也不是微不足道的。 (關於Unicode很少很容易理解:人類語言加載了特殊情況)。我可以建議看一下GLib的'g_utf8_strlen'嗎?它不能解決你的緊急問題,但你會學到很多。 http://git.gnome.org/cgit/glib/tree/glib/gutf8.c – quark 2009-11-13 19:45:01

+0

@Miroslav:是的,我嘗試了這個解決方案,但它給了我雙重打印。 – 2009-11-13 20:06:39

回答

3

通常情況下,您需要將字符串存儲在wchar_t中,並使用類似ansi_strlen的長度來獲取它的長度 - 這會給您打印的字符數,而不是您存儲的字節數。

你真的不應該實現UTF或Unicode或任何多字節字符處理自己 - 有這樣的事情庫。

+0

我不熟悉這些庫(來自Java世界)。我實現了Michal Sznajder對這些字符的破解,所以我希望能有類似這樣的解決方案。 – 2009-11-13 19:37:12

+0

這可能是你需要的一切:http://www.tablix.org/~avian/blog/archives/2009/10/more_about_wchar_t/ – 2009-11-13 19:44:08

+0

我同意這一點。在這個問題下查看關於GLib的'g_utf8_strlen'的評論。 – quark 2009-11-13 19:45:33

0

編輯:您使用的語言環境是什麼?

如果你打算通過迭代在一個字符串上,不要打擾與strlen得到它的長度。只是重複,直到你看到一個NUL字符:

char *p = str; 
while(*p != '\0') { 
    printf("%c\n", *p); 
    ++p; 
} 

至於umlauted字符,這樣,他們是UTF-8?如果字符串是多字節,你可以做這樣的事情:

size_t n = strlen(str); 
char *p = str; 
char *e = p + n; 
while(*p != '\0') { 
    wchar_t wc; 
    int l = mbtowc(&wc, p, e - p); 
    if(l <= 0) break; 
    p += l; 
    /* do whatever with wc which is now in wchar_t form */ 
} 

我真的不知道,如果mbtowc將簡單地返回-1如果它在一個MB字符的中間遇到NUL。如果是這樣,您可以通過MB_CUR_MAX而不是e - p,並取消撥打strlen的電話。但我有一種感覺,這是不是的情況。

+0

我不確定...在思考charsets方面是全新的。正如有人在上一個問題中提出的那樣,它看起來像輸入是UTF-8,但代碼集是ASCII ... – 2009-11-13 19:42:58

+0

此外,您的代碼在行\t中給出錯誤p + = mbtowc(&wc,p,n - p) ; 對二進制無效的操作數 - – 2009-11-13 19:48:49

+0

哎呀,修正了這個問題。這就是我沒有編譯發佈的內容。 – 2009-11-13 19:50:14

0

你可以做類似

for (int i = 0; str[i]!='\0'; ++i){ 
    //do something with str[i] 
} 

字符串中C被終止 '\ 0'。所以可以像這樣檢查字符串的結尾。

+0

夠簡單,但不適用於虛擬人物。 – 2009-11-13 20:09:34

+0

這是我做的,至今令人驚訝的作品: '\t //循環,直到我們得到一個NULL字符 \t的for(int i = 0; STR [1] = '\ 0'; ++我!) \t { \t \t unsigned char letter = str [i]; \t \t \t // \t如果我們有一個元音變音,讀出下一個字符代替 \t \t如果(0xC3 ==字母) \t \t \t的printf( 「%S」,to_morse(STR [++ I])) ; \t \t else \t \t \t printf(「%s」,to_morse(str [i])); \t} \t」 然後我取下,letter_Nr元音字符檢查。 – 2009-11-13 20:44:58

1

在OS X上,可可一個解決方案 - 請注意使用的NSLog「%C」 - 這是一個單字符(16位Unicode字符):

#import <Cocoa/Cocoa.h> 

int main() 
{ 
     NSAutoreleasePool * pool = [NSAutoreleasePool new]; 
     NSString * input = @"Hej du kalleåäö"; 

     printf("length of str: %d", [input length]); 
     int i=0; 
     for (i = 0; i < [input length]; i++) 
     { 
       NSLog(@"%C", [input characterAtIndex:i]); 
     } 

     [pool release]; 
}