wchar_t gcc

本文探讨了wchar_t在Windows和Linux操作系统上的不同大小,并通过实例展示了如何在使用wchar_t时遇到的问题及其解决策略。重点介绍了如何通过GCC编译器选项-fshort-wchar来调整wchar_t的大小,以及在处理wchar_t相关的函数时可能出现的意外情况,如字符转换和字符串长度计算。此外,文章还提供了解决这些问题的方法,包括根据wchar_t的实际大小进行代码调整和使用模板来处理不同大小的wchar_t。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

wchar_t   gcc

from: http://bbs.chinaunix.net/archiver/?tid-1350913.html

在WIN上wchar_t是2个字节 Linux上是4个字节
gcc 有选项-fshort-wchar 把wchar_t 编译成2个字节

但用着怎么有问题呢?

test.cpp

#include   <stdio.h>
#include   <stdlib.h>
#include <string.h>
#include <wctype.h>
#include <wchar.h>
using namespace std ;

int  main()
{
      wchar_t   *wcs   =   L"this";
        char a_szDest[50] ;
        int count = wcstombs(a_szDest,wcs,50) ;
        printf("sizeof(wchar_t)=%d/n",sizeof(wchar_t)) ;
        printf("count=%d/n",count);
        printf("dest=%s/n",a_szDest);
        printf("%d/n",wcslen(wcs)) ;
        return 0 ;
}

1、不用选项-fshort-wchar 编译
g++ -o test test.cpp
结果:
sizeof(wchar_t)=4
count=4
dest=this
4

2、用选项编译
g++ -o test test.cpp -fshort-wchar
结果:
sizeof(wchar_t)=2
count=-1
dest=
13

现在 wcslen(wcs)) 怎么成了13

/

from:http://blog.youkuaiyun.com/Nhsoft/archive/2008/04/10/2280237.aspx

疯狂的wchar_t 收藏

疯狂的wchar_t
PS: 我还是改个标题,不改怕被高手们骂死。

    去年的这个时候当我决定把所有渲染和支持代码都向d3d10转移的时候,就准备搞定以后多语言的问题,于是义无反顾的选择了unicode。unicode处理中文字符串时候方便多了----至少在windows下是如此。
    基于这个出发点,我的xml解析器直接处理的就是unicode文本,而不是常见的utf-8。(注,用记事本保存成unicode编码而不是utf-8,见附图,2008-12-10注 ) 一切都很美好,知道我离开windows。上个礼拜,我需要把程序移植到linux下。在编译完程序后,xml加载器首先就罢工了。gdb跟踪进去发现, 竟然我取到的一个字符是负数,当时差点没晕倒。想了好长时间没想明白。楞了一个下午才反应过来sizeof(wchar_t) != 2 .....。除了xml文件,我的文件打包器的name成员是wchar_t。意味着我在windows下打包的文件时候在linux下一定会出问题。
    考察了很久,猛然发现gcc有个option叫-fshort_wchar。 激动之,赶快加一个,make clean && make。---结果还是挂! 又让我郁闷了好久,继续gdb。发现wcslen(str)竟然短一半----原来glibc里的wchar_t还是4个字节。看来要使用 -fshort_wchar还必须要编译glibc。
    没办法,只能判断wchar_t长短来处理了。目前我的做法是准备做一个template,根据sizeof(wchar_t)来选择使用哪个字符串,保 存在文件里的字串通通按照ucs-2来处理。并在加载时候来进行ucs-2/ucs-4转换。不敢轻易下决策了。等想一阵再说。看来unicode也不省 心啊,家家都有本难念的经。 

    注:ucs分ucs2和ucs4,就是16bit和32bit的。utf8和utf16/utf32则是编码方式。utf8的anscii码基本和 ansi一样。可以使用libiconv来进行各种编码方式之间转化。 编译器里的unicode通常是ucs-2-internal和ucs-4-internal。

 

     附:目前我处理带wchar_t需要保存的结构体。

struct sCDDataEntryItem
{
public:
      int                     m_StartAddr;           /*long 4 - byte : FileStartAt */
      xcd_data_type  m_DataType;
      int                     m_DataCompressedSize; /*long 4 - byte : PackedSize */
      int                     m_DataSize;         /*long 4 - byte : FileSize-Without packed */

      int                     m_CompressedRate;       /**/
      int                     m_Reserved ;         /*long 4 - byte : Reserved */

protected:
      unsigned short m_utf16Name[128];

public:

      virtual wchar_t*  getDataName() = 0;
     virtual void      ValidateName() = 0;
      virtual void      SetDataName(const wchar_t* name) = 0;

public:
  sCDDataEntryItem()
  {
     m_StartAddr = 0;           /*long 4 - byte : FileStartAt */
     m_DataType = xcddt_common;
     m_DataCompressedSize = 0; /*long 4 - byte : PackedSize */
     m_DataSize = 0;         /*long 4 - byte : FileSize-Without packed */

     m_CompressedRate = XCOMDOC_NOCOMPRESS;       /**/
     m_Reserved  = 0 ;         /*long 4 - byte : Reserved */
     memset(m_utf16Name,0,sizeof(unsigned short)*128);      /*char       128 - byte : File Name(Readable) */
   }
};


template <int UCSTYPE> class  T_CDDataEntryItemImp : public sCDDataEntryItem
{
};

template <> class  T_CDDataEntryItemImp<2> : public sCDDataEntryItem
{
public:
    wchar_t*  getDataName()
    {
        return  (wchar_t*)m_utf16Name;
    }
    void ValidateName()
    {

    }
    void SetDataName(const wchar_t* name)
    {
        wcscpy( (wchar_t*)m_utf16Name,name);
    }
};

template <> class  T_CDDataEntryItemImp<4> : public sCDDataEntryItem
{
    unsigned int   m_ucs4DataName[128];
public:
    wchar_t*  getDataName()
    {
        if(sizeof(wchar_t) == 4)
            return (wchar_t*)m_ucs4DataName;
    }
    void ValidateName()
    {
         XEvol_UCS2ToUCS4(m_utf16Name , m_ucs4DataName,128,128);
    }

    void SetDataName(const wchar_t* name)
    {
        wcscpy( (wchar_t*)m_ucs4DataName,name);
        XEvol_UCS4ToUCS2(m_ucs4DataName , m_utf16Name ,128,128);
       
    }

    T_CDDataEntryItemImp()
    {
        memset(m_ucs4DataName , 0, sizeof(wchar_t) * 128);
    }
};

typedef T_CDDataEntryItemImp<sizeof(wchar_t)> CDDataEntryItemImp;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值