LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 4953|回复: 19

有关wchar_t

[复制链接]
发表于 2005-4-13 02:21:28 | 显示全部楼层 |阅读模式

  1.         wchar_t *p;

  2.         setlocale(LC_ALL, "");
  3.         p = L"中华人民共和国a";
  4.         wprintf(L"%d\n", wcslen(p));
复制代码


这段代码在linux下面,或在win32上用mingw,gcc -D_UNICODE编译,输出的都是15,怎么会这样啊?
另,win32上有个_mbslen函数,gcc里有没有类似功能的东西呢?
发表于 2005-4-13 09:54:10 | 显示全部楼层
首先要设置你的locale为zh_cn.utf8。
确保你的程序源代码为utf8编码。
因为你的"中华人民共和国"为utf8编码,所以使用mbrtowc转换为unicode编码。
然后可以用wcslen了。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-4-13 20:15:56 | 显示全部楼层
今天不方便用linux测试,我用mingw测试了一下。代码是utf8编码,用gcc -D_UNICODE编译上面这段程序,输出变成了22,不知道是怎么搞的。

mbrtowc我查了一下,解释和函数原形如下:
size_t mbrtowc(wchar_t *pwc, const char *s, size_t n, mbstate_t *ps);
convert multibyte character to wide character using conversion states

既然程序中已经是wchar_t,而且字符串也已经用TEXT宏,还需要用这个函数再转一次么?
回复 支持 反对

使用道具 举报

发表于 2005-4-14 09:50:35 | 显示全部楼层
mingw是调用vc c运行时库的,结果和标准c库不同的。
建议你到linux下去试。
另外用户输入的字符串都是mbs编码,不是原生unicode形式,所以一定要转下编码的。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-4-14 15:25:40 | 显示全部楼层
在linux里测试,上面那段代码,内码为gbk时输出15,为utf8和unicode时输出22,糊涂了说。
同样的代码,不管内码是什么,vc的输出都是8。
呵呵,完全糊涂了说。
回复 支持 反对

使用道具 举报

发表于 2005-4-15 16:18:42 | 显示全部楼层
输出是8是对的。如果输出其他个数,说明编译器、编辑器对UNICODE支持不好。
回复 支持 反对

使用道具 举报

发表于 2005-4-15 17:33:16 | 显示全部楼层

在我的linux box编译通过的代码,输出为8

楼主概念不清,utf8和unicode是两码事呀,怎能混为一谈。
utf8表述一个字符有可能会用到5个字节,而unicode目前两种流行的实现。
ucs2两个字节,ucs4四个字节。

  1. #include <stdio.h>
  2. #include <locale.h>
  3. #include <wchar.h>
  4. int main()
  5. {
  6.     size_t len;
  7.     char * locp;
  8.     char *src="中华人民共和国a";
  9.     size_t nbytes;
  10.     wchar_t dst[100];

  11.     mbstate_t state;
  12.     memset (&state, '\0', sizeof (state));

  13.     len = strlen(src);
  14.     printf("mbs len is %d\n",len);

  15.     locp = setlocale(LC_ALL, "zh_CN.gbk");
  16.     printf("You have set Locale to %s\n",locp);
  17.     mbsrtowcs(dst,&src,len,&state);        
  18.     printf("%d\n", wcslen(dst));
  19.    //如果用ssh,尝试一下将转换后的字符串输出,如果是真实终端,结果只能是乱码
  20.   printf("%ls\n",dst);
  21.     return 0;
  22. }
复制代码
回复 支持 反对

使用道具 举报

发表于 2005-4-15 17:36:38 | 显示全部楼层
你自己没整对,还说gcc不好,真是怪事。
井底之蛙。
windows nt的内核只认识ucs2,所以会自动都会把所有各种各样的编码按照缺省的locale自动转化为ucs2编码,结果当然正确了。可是这是标准c的做法吗?很明显,这不是。这是偷懒的做法。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-4-17 03:03:43 | 显示全部楼层
哈哈,好敏感的人说。俺不想讨论标准或是偷懒之类的问题,realtang其实也没看清楚我到底在问什么。
我不太清楚标准c到底是怎么定义的,不过就我在网上看到的资料都说,源码中TEXT宏包裹的字符都被当作宽字符来处理。像我一楼这样的程序,字符串常量我已经写明了当作宽字符来处理,我奇怪的是为什么输出的字符串长度不正确。如果说源代码的内码跟编译结果也有关系,那要让上面那段程序输出8,我应该在什么local中编译什么内码的程序?
我在zh_CN.GBK和POSIX中编译了gbk、utf8和unicode(iconv -f GBK -t XXX)的代码,可是结果都不正确,我问的是这个。

呵,也是我多嘴。
回复 支持 反对

使用道具 举报

发表于 2005-4-18 09:59:06 | 显示全部楼层
Post by 800
哈哈,好敏感的人说。俺不想讨论标准或是偷懒之类的问题,realtang其实也没看清楚我到底在问什么。
我不太清楚标准c到底是怎么定义的,不过就我在网上看到的资料都说,源码中TEXT宏包裹的字符都被当作宽字符来处理。像我一楼这样的程序,字符串常量我已经写明了当作宽字符来处理,我奇怪的是为什么输出的字符串长度不正确。如果说源代码的内码跟编译结果也有关系,那要让上面那段程序输出8,我应该在什么local中编译什么内码的程序?
我在zh_CN.GBK和POSIX中编译了gbk、utf8和unicode(iconv -f GBK -t XXX)的代码,可是结果都不正确,我问的是这个。

呵,也是我多嘴。

你看的资料在误导你,用L前缀的话,在标准c里后面的双引号里的内容应是usc2或者ucs4编码。
比如NULL的表示,不加前缀的话就是'\0',加L前缀的话编译器就把他置为'\0\0',多了一个'\0'.。这才是L前缀的标准用法。标准c才不会把你的L前缀表示的字符串给你自动转换,那是程序员的职责。
知道不。至于微软的编译器可能是因为太强大了,所以给你来个自动转换。知道不。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表