用模糊字符对字符串/ strlen进行迭代
这是对我的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函数,但我不知道这是否是一个漂亮/合理的解决方案。
通常情况下,您需要将字符串存储在wchar_t
中,并使用类似ansi_strlen
的长度来获取它的长度 - 这会给您打印的字符数,而不是您存储的字节数。
你真的不应该实现UTF或Unicode或任何多字节字符处理自己 - 有这样的事情库。
我不熟悉这些库(来自Java世界)。我实现了Michal Sznajder对这些字符的破解,所以我希望能有类似这样的解决方案。 – 2009-11-13 19:37:12
这可能是你需要的一切:http://www.tablix.org/~avian/blog/archives/2009/10/more_about_wchar_t/ – 2009-11-13 19:44:08
我同意这一点。在这个问题下查看关于GLib的'g_utf8_strlen'的评论。 – quark 2009-11-13 19:45:33
编辑:您使用的语言环境是什么?
如果你打算通过迭代在一个字符串上,不要打扰与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
的电话。但我有一种感觉,这是不是的情况。
我不确定...在思考charsets方面是全新的。正如有人在上一个问题中提出的那样,它看起来像输入是UTF-8,但代码集是ASCII ... – 2009-11-13 19:42:58
此外,您的代码在行\t中给出错误p + = mbtowc(&wc,p,n - p) ; 对二进制无效的操作数 - – 2009-11-13 19:48:49
哎呀,修正了这个问题。这就是我没有编译发布的内容。 – 2009-11-13 19:50:14
你可以做类似
for (int i = 0; str[i]!='\0'; ++i){
//do something with str[i]
}
字符串中C被终止 '\ 0'。所以可以像这样检查字符串的结尾。
够简单,但不适用于虚拟人物。 – 2009-11-13 20:09:34
这是我做的,至今令人惊讶的作品: '\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
在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];
}
您是否尝试过在该回复中描述的解决方案到你以前的问题? http://stackoverflow.com/questions/1725124/accented-umlauted-characters-in-c/1725169#1725169 – 2009-11-13 19:38:18
@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
@Miroslav:是的,我尝试了这个解决方案,但它给了我双重打印。 – 2009-11-13 20:06:39