2009-11-13 64 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]; 
}