LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
12
返回列表 发新帖
楼主: 800

有关wchar_t

[复制链接]
 楼主| 发表于 2005-4-18 15:44:56 | 显示全部楼层
哈哈哈,受教了。可能是我比较衰,或者比较笨吧。本来回贴前想去做点功课的,可找了一个小时,实在找不到gcc有关这方面的详细资料。没办法,不得不老着脸皮再问一句了,要想让我一楼的那段程序输出8,应该怎么做?
回复 支持 反对

使用道具 举报

发表于 2005-4-20 11:23:56 | 显示全部楼层
偷学习了不少东西,呵呵

我的理解是,源代码使用的编码在编写程序的时候就已经固定了,输入的中文字符串在源码中会根据编码的不同而不同,但绝对不会存储为unicode,因此在字符串前面加“L"几乎是没有意义的(是几乎)。我们在源码中输入的都是msb,不可能输入unicode。因此要想输出8只能按realtang的方法实现,即msb转换为unicode。

不知道我说的对不对,欢迎高手拍砖
另外问一下,那“L”一般在什么情况下使用阿,只能在windows下用吗?
如果这样的话,是否会有源码移植的问题?比如我用utf8写源码,别人用gbk编译,那是不是就要出乱码了?这要是不是要求我们在源码里面不要写汉字字符串了,而是使用gettext等实现字符串变量
回复 支持 反对

使用道具 举报

发表于 2005-4-20 13:58:05 | 显示全部楼层
Post by lit_river
偷学习了不少东西,呵呵
另外问一下,那“L”一般在什么情况下使用阿,只能在windows下用吗?

比如你使用ansi编码,有个字符串"Hello world"。
你使用了w开头的一些函数,他们需要提供wchar类型的参数,那么你就可以L"Hello world"。
但是你可不能把mbs编码的字符串加L前缀。必须要用mbsrtowcs函数先转换。
至于你真实输入的编码类型,比如是gbk或者utf,那么你就先要用setlocale函数先设置为你的实际编码类型。
另外重要的是,linux下你使用setlocale时,你需要用的locale必须已经安装。
安装的方法,debian 方法是:dpkg-reconfigure locales
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-4-21 10:57:32 | 显示全部楼层
Post by lit_river
偷学习了不少东西,呵呵

我的理解是,源代码使用的编码在编写程序的时候就已经固定了,输入的中文字符串在源码中会根据编码的不同而不同,但绝对不会存储为unicode,因此在字符串前面加“L"几乎是没有意义的(是几乎)。我们在源码中输入的都是msb,不可能输入unicode。因此要想输出8只能按realtang的方法实现,即msb转换为unicode。

不知道我说的对不对,欢迎高手拍砖
另外问一下,那“L”一般在什么情况下使用阿,只能在windows下用吗?
如果这样的话,是否会有源码移植的问题?比如我用utf8写源码,别人用gbk编译,那是不是就要出乱码了?这要是不是要求我们在源码里面不要写汉字字符串了,而是使用gettext等实现字符串变量


我想首先可以肯定的是,L前缀是会导致字符串编码转换的。我在试验的时候不管是gbk还是utf8的内码,最后的输出都是15。"中华人民共和国a"这个字符串在gbk内码下,字节数是15,但在utf8下肯定无论字节数还是字符数都不是15。就到目前为止的情况来看,L前缀的作用仍然是声明宽字符。但不管怎么做,gcc本身似乎最多就只能将ascii和unicode进行转换,再多的就做不到了。
L前缀具体规定有什么用途我也不太清楚,就我的试验来看就是申明宽字符,进行ascii和unicode的转换。不过其实也不太一定,因为我在别人的代码里见到过用L前缀声明的非ascii宽字符,就是那个“(C)”。也可能是gcc自己能做的只是单字节字符和unicode的转换。
不管是mbsrtowcs还是gettext,虽然可能都可行,但都显得有些罗嗦。而且我的疑问仍然存在,即要让一楼的程序输出8应该怎么做,还是说gcc根本就做不到。
回复 支持 反对

使用道具 举报

发表于 2005-4-21 11:24:49 | 显示全部楼层
楼主你就省省吧,你程序写成那样,gcc根本做不到。要知道,在linux下,甚至没有wstdout的概念。linux的内核根本就没实现,所以你根本没法使用wprintf。
回复 支持 反对

使用道具 举报

发表于 2005-10-10 18:38:58 | 显示全部楼层
Post by 800

  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里有没有类似功能的东西呢?


你的程序从思路上开始就出错了,看来你并没有了解宽字符该如何使用。这也难怪,市面上的书很少有专门讲解国际化软件开发的。大部分书都是教导我们要有开发国际化软件的思想,但对于具体怎么做,没有哪本书系统的提及。我在这个方面也徘徊了好久。
好好看看这篇文章《寬字元與多位元組字元》,里面讲的很清楚。这是好不容易从Internet大海里搜出来的。可以算Linux/glibc下开发国际化软件的bible了。中文的。台湾人的研究成果。

《寬字元與多位元組字元》《親手打造 GNU/Linux 中文環境》系列文章的一部分。《親手打造 GNU/Linux 中文環境》详细讲解了glibc中的i18n的全部内容,里面的“宽字符”“gettext”相关章节对于理解国际化程序设计帮助非常大。
回复 支持 反对

使用道具 举报

发表于 2005-10-10 21:21:05 | 显示全部楼层
我说呢
我试过找
没有找到
真是太谢谢了
回复 支持 反对

使用道具 举报

发表于 2006-5-15 17:20:37 | 显示全部楼层

真是好贴啊,刷起来

受益匪浅,up起来。

不过我在gcc下编译时,realtang的代码中mbsrtowcs(dst,&src,len,&state);这一行需要改成mbsrtowcs(dst,(const char**)&src,len,&state); 才行。

也就是第二个参数要做(const char**)强转。
回复 支持 反对

使用道具 举报

发表于 2006-5-16 10:11:30 | 显示全部楼层
gcc-4.0以上好像已经支持L前缀windows c的同样用法了。
回复 支持 反对

使用道具 举报

发表于 2006-5-16 16:25:21 | 显示全部楼层
今天看了一下oreilly的posix programmers guide。
我现在的理解:mbs基本上类似utf8,是不定长的,而wcs是定长的类似unicode。
定长的wcs可以随机访问,但是效率较差,浪费空间。
源代码中的字符串都是mbs编码。

不知道对不对。
回复 支持 反对

使用道具 举报

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

本版积分规则

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