当前位置: 亚洲城ca88 > ca88 > 正文

multibyte和unicode互相调换时求长度的多个函数

时间:2019-08-01 23:06来源:ca88
在实质上编制程序中时常会遇见多字节本地码字符串和unicode字符串之间的相互转化,函数是有,可是要大家保障缓冲区的长度正确,多则浪费,少了就内部存款和储蓄器溢出,正确求长

在实质上编制程序中时常会遇见多字节本地码字符串和unicode字符串之间的相互转化,函数是有,可是要大家保障缓冲区的长度正确,多则浪费,少了就内部存款和储蓄器溢出,正确求长度 是任重先生而道远。

将string|char*转换为wstring|wchar_t*的例子:
1、string转换为wstring:
string str=_T("翔翔糖糖");
int size=MultiByteToWideChar(CP_ACP,0,str.c_str(),-1,NULL,0);
wchar_t *ch=new wchar_t[size 1];
if(!MultiByteToWideChar(CP_ACP,0,str.c_str(),-1,ch,size))
{ return false;}

 

举例大家要将三个多字节串调换来unicode:

wstring wstr=ch;
2、char*转换为wchar_t*:
char *str=_T("翔翔糖糖");
int size=MultiByteToWideChar(CP_ACP,0,str,-1,NULL,0);
wchar_t *ch=new wchar_t[size 1];
if(!MultiByteToWideChar(CP_ACP,0,str,-1,ch,size))
{ return false;}
MultiByteToWideChar使用例子 
char* OleDBCom::UnsignedShortToCharp(unsigned short *strU)

UINT nStrULength=WideCharToMultiByte(
CP_ACP,0,strU,-1,NULL,NULL,NULL,NULL);
LPSTR lpStr;
lpStr=(char*)malloc(nStrULength); 
WideCharToMultiByte(CP_ACP,0,strU,-1,lpStr,nStrULength,NULL,NULL);
return lpStr;
}
unsigned short* OleDBCom::CharpToUnsignedShort(LPSTR str)
{
OLECHAR strU[255];
int nStatus=MultiByteToWideChar(CP_ACP,0,str,-1,strU,255); 
return strU;
}
====================
HRESULT __fastcall AnsiToUnicode(LPCSTR pszA, LPOLESTR* ppszW)
{
   ULONG cCharacters;
   DWORD dwError;
   if (NULL == pszA)
   {
     *ppszW = NULL;
     return NOERROR;
   }
   cCharacters = strlen(pszA) 1;
   *ppszW = (LPOLESTR) CoTaskMemAlloc(cCharacters*2);
   if (NULL == *ppszW)
     return E_OUTOFMEMORY;
   if (0 == MultiByteToWideChar(CP_ACP, 0, pszA, cCharacters,
       *ppszW, cCharacters))
   {
     dwError = GetLastError();
     CoTaskMemFree(*ppszW);
     *ppszW = NULL;
     return HRESULT_FROM_WIN32(dwError);
   }
return NOERROR;
此地有个例证,
PWSTR pWideCharStr;
int nLenOfWideCharStr;
率先总计要求的宽字符串的字符数
nLenOfWideCharStr=MultiByteToWideChar(CP_ACP,0,pMultiByteStr,-1,NULL,0)
那边的pMultiByteStr是要改换的多字节字符。
给pWideCharStr分配内部存款和储蓄器块
pWideCharStr=HeapAlloc(GetProcessHeap(),0,nLenOfWideCharStr*sizeof(WCHAR));
接下来把多字节字符串调换到宽字符串
MultiByteToWideChar(CP_ACP,0,pMultiByteStr,-1,pWideCharStr,nLenOfWideCharStr)

char 转wchar_t 及wchar_t转char

初稿来自

选用widechartomultibyte来改换的函数

平凡适合于window平台上利用

#include <tchar.h>

#include <windows.h>

int _tmain(int argc, _tchar* argv[])

{

wchar_t pwstr[] =l"作者是华夏人";

wchar_t pwstr2[20];

    char *pcstr = (char *)malloc(sizeof(char)*(2 * wcslen(pwstr) 1));

    memset(pcstr , 0 , 2 * wcslen(pwstr) 1 );

    w2c(pcstr,pwstr,2 * wcslen(pwstr) 1) ;

    printf("%sn",pcstr);

c2w(pwstr2,20,pcstr);

wprintf(l"%s",pwstr2);

    free(pcstr) ;

return 0;

}

//将wchar_t* 转成char*的贯彻函数如下:

char *w2c(char *pcstr,const wchar_t *pwstr, size_t len)

{

int nlength=wcslen(pwstr);

//获取调换后的尺寸

int nbytes = WideCharToMultiByte( 0, // specify the code page used to perform the conversion

0,         // no special flags to handle unmapped characters

pwstr,     // wide character string to convert

nlength,   // the number of wide characters in that string

NULL,      // no output buffer given, we just want to know how long it needs to be

0,

NULL,      // no replacement character given

NULL );    // we don't want to know if a character didn't make it through the translation

// make sure the buffer is big enough for this, making it larger if necessary

if(nbytes>len)   nbytes=len;

// 通过以上获得的结果,转变unicode 字符为ascii 字符

WideCharToMultiByte( 0, // specify the code page used to perform the conversion

0,         // no special flags to handle unmapped characters

pwstr,   // wide character string to convert

nlength,   // the number of wide characters in that string

pcstr, // put the output ascii characters at the end of the buffer

nbytes,                           // there is at least this much space there

NULL,      // no replacement character given

NULL );

return pcstr ;

}

//将char* 转成wchar_t*的兑现函数如下:

//那是把asii字符转变为unicode字符,和方面同样的规律

void c2w(wchar_t *pwstr,size_t len,const char *str)

{

if(str)

    {

      size_t nu = strlen(str);

      size_t n =(size_t)multibytetowidechar(cp_acp,0,(const char *)str,(int)nu,null,0);

      if(n>=len)n=len-1;

      multibytetowidechar(cp_acp,0,(const char *)str,(int)nu,pwstr,(int)n);

   pwstr[n]=0;

    }

}

要么用此种方法越来越好一些:============作者自已做的

//把ascii 字符转变为unicode字符

wchar_t* Cphone_hq::ctow(wchar_t *pwstr, const char *str)

{

wchar_t* buffer;

if(str)

    {

      size_t nu = strlen(str);

      size_t n =(size_t)MultiByteToWideChar(CP_ACP,0,(const char *)str,int(nu),NULL,0);

   buffer=0;

      buffer = new wchar_t[n 1];

      //if(n>=len) n=len-1;

   ::MultiByteToWideChar(CP_ACP,0,(const char *)str,int(nu),buffer,int(n));    

   }

return buffer;

delete buffer;

}

相关知识点:

Unicode的面世是为着适应软件国际化的须求。Unicode不一样于双字节字符集(DBCS)。

一、相关操作函数

       1、DBCS使用上面包车型地铁函数操作字符串:

             CharNext——获得后八个字符

            CharPrev——获得前一个字符

            IsDBCSLeadByte——判别是否为多个字节字符的首先个字节

            C 运转期库提供了以"_mbs"初阶的一各样的函数操作DBCS。类似的函数有_mbscat等。

       2、ANSI字符集是三个美利坚联邦合众国正规。C 运维期库提供了以"str"开始的一部分列的函数操作此字符集。

       3、C 运营期库为Unicode字符集提供了一各种以"wcs"开头的函数。

二、对应的数据类型

       1、对于ANSI字符定义为char。

        2、对于Unicode的字符定义为wchar_t。

三、使用条件

       1、首先要验证的是Win98对此Unicode的支撑是很虚亏的,所以假若要在Win98上运维Unicode编写翻译的顺序,只怕导致运营错误大概退步。

       2、 由于Win三千及未来的OS的内核都以选拔Unicode编写的,所以就算可以在其上运转ANSI编码的主次,然则其运作进程中许多地点都急需将 ANSI转变为Unicode现在,调用Unicode版本的函数,因为那些调换的长河存在所以ANSI的程序运维效能不高。在Win三千上最棒使用 Unicode编写程序。

四、编写通用的次第

       1、在编制程序的时候使用TCHACR-V数据类型,此类型能够依照预编写翻译宏的概念,将其转移为ANSI恐怕是Unicode。

       2、预编写翻译宏_MBCS、_UNICODE和UNICODE。_MBCS是多字节和ANSI字符串的编写翻译宏。此时TCHA猎豹CS6将更改为char。_UNICODE和UNICODE是Unicode编码的预编写翻译宏,TCHALAND将转移为wchar_t。

       3、_UNICODE和UNICODE与_MBCS不可能在编写翻译的时候还要被定义。

       4、_UNICODE宏用于C运维期库的头文件,UNICODE宏用于Windows头文件。一般同一时间定义那四个宏。

五、转换函数

       1、Unicode转换为ANSI使用:MultiByteToWideChar。

       2、ANSI转换为Unicode使用:WideCharToMultiByte。

 

宽字符转多字符:

       size_t wcstombs(char *mbstr, const wchar_t *wcstr, size_t count );

多字符转宽字符:

       size_t mbstowcs(wchar_t *wcstr, const char *mbstr, size_t count );

       另:L"ab"是C/C 标准宏,使用上是没有问题的

      1、client 里某个函数接口须要unicode,那几个由于能源也在本地,能够平昔运用MultiByteToWideChar可能mbstowcs setlocale 转换

       2、对于急需从 中文client->服务器->马耳他语client的措施下,在传文本的动静下,要求将文字的言语代码一齐传出去,在接受端可以选择内定的代 码,转变。服务器如有须求的话,也得以行使该代码转换,那样就足以在client上同不经常间出示多国语言了

const char * str = "1二3四";

WideCharToMultiByte和MultiByteToWideChar函数的用法
为了支持Unicode编码,供给多字节与宽字节时期的互相转变。
那八个系统函数在使用时需求内定代码页,在实际应用进度中碰着乱码难点,
接下来再一次翻阅《Windows宗旨编制程序》,计算出科学的用法。
WideCharToMultiByte的代码页用来标志与新转变的字符串相关的代码页。
MultiByteToWideChar的代码页用来标志与三个多字节字符串相关的代码页。
常用的代码页由CP_ACP和CP_UTF8两个。
使用CP_ACP代码页就达成了ANSI与Unicode之间的调换。
使用CP_UTF8代码页就落到实处了UTF-8与Unicode之间的更改。
上面是代码达成:
1. ANSI to Unicode
wstring ANSIToUnicode( const string& str )
{
int len = 0;
len = str.length();
int unicodeLen = ::MultiByteToWideChar( CP_ACP,
    0,
    str.c_str(),
    -1,
    NULL,
    0 ); 
wchar_t * pUnicode; 
pUnicode = new    ]; 
memset(pUnicode,0,(unicodeLen 1)*sizeof(wchar_t)); 
::MultiByteToWideChar( CP_ACP,
   0,
   str.c_str(),
   -1,
   (LPWSTR)pUnicode,
   unicodeLen ); 
wstring rt; 
rt = ( wchar_t* )pUnicode;
delete pUnicode; 
return rt; 
}
2. Unicode to ANSI
string UnicodeToANSI( const wstring& str )
{
char* pElementText;
int iTextLen;
iTextLen = WideCharToMultiByte( CP_ACP,
   0,
   str.c_str(),
   -1,
   NULL,
    0,
   NULL,
   NULL );
pElementText = new char[iTextLen   1];
memset( ( void* )pElementText, 0, sizeof( char ) * ( iTextLen   1) );
::WideCharToMultiByte( CP_ACP,
   0,
   str.c_str(),
   -1,
   pElementText,
   iTextLen,
   NULL,
   NULL );
string strText;
strText = pElementText;
delete[] pElementText;
return strText;
}
3. UTF-8 to Unicode
wstring UTF8ToUnicode( const string& str )
{
int len = 0;
len = str.length();
int unicodeLen = ::MultiByteToWideChar( CP_UTF8,
    0,
    str.c_str(),
    -1,
    NULL,
    0 ); 
wchar_t * pUnicode; 
pUnicode = new wchar_t[unicodeLen 1]; 
memset(pUnicode,0,(unicodeLen 1)*sizeof(wchar_t)); 
::MultiByteToWideChar( CP_UTF8,
   0,
   str.c_str(),
    -1,
   (LPWSTR)pUnicode,
   unicodeLen ); 
wstring rt; 
rt = ( wchar_t* )pUnicode;
delete pUnicode; 
return rt; 
}
4. Unicode to UTF-8
string UnicodeToUTF8( const wstring& str )
{
char*   pElementText;
int iTextLen;
iTextLen = WideCharToMultiByte( CP_UTF8,
   0,
   str.c_str(),
   -1,
   NULL,
   0,
   NULL,
   NULL );
pElementText = new char[iTextLen   1];
memset( ( void* )pElementText, 0, sizeof( char ) * ( iTextLen   1) );
::WideCharToMultiByte( CP_UTF8,
   0,
   str.c_str(),
   -1,
   pElementText,
   iTextLen,
   NULL,
   NULL );
string strText;
strText = pElementText;
delete[] pElementText;
return strText;

该串strlen求得长度是6,假诺大家就以6 1分配wchar_t空间,肯定是种浪费,因为实在该串唯有4个字符,所以,用4 1分配就足足。

#include "stdafx.h" 
#include "string.h" 
#include "stdio.h" 
#include "windows.h" 
int main(int argc, char* argv[]) 

char temp[20]; 
int nLen; 
LPWSTR name = L"CPU"; 
sprintf(temp,"CPUd",i); 
nLen = MultiByteToWideChar(CP_ACP,0,temp,-1,NULL,0); 
MultiByteToWideChar(CP_ACP,0,temp,-1,(LPWSTR)name,nLen); 
WideCharToMultiByte(CP_ACP,0,(LPWSTR)name,-1, strs,100,NULL,NULL); 
printf("good: %s n",name); 
return 0; 

调试时,在MultiByteToWideChar处报错 
MultiByteToWideChar 函数把叁个字符串映射为贰个宽字符串。被这些函数映射的字符串不必属于多字节字符集。 

故此,大家须要用到自家提供的函数ansiCharsCount()。它将赶回4。

    返回值: 
若该函数成功,且 cchMultiByte 为非零值,则再次来到值是写入由 lpWideCharStr 针对的缓冲区中的宽字符数。
若该函数成功,且 cchMultiByte 为零,则重返值是以宽字符为单位的缓冲区大小值。该缓冲区能够选拔转变后的字符串。 
若该函数失利,则再次回到值为FALSE,调用GetLastErro可得到补偿的错误音讯。 

int length = ansiCharsCount( str );

1   //--------------------------------------------------------------------------- 
   //函数输入Big5字符,再次回到Gb简体字符   //一遍转变
    //--------------------------------------------------------------------------- 
    AnsiString __fastcall Big2Gb(AnsiString sBig) 
    { 
    char* pszBig5=NULL; //Big5编码的字符 
    wchar_t* wszUnicode=NULL; //Unicode编码的字符 
    char* pszGbt=NULL; //Gb编码的繁体字符 
    char* pszGbs=NULL; //Gb编码的简体字符 
    AnsiString sGb; //重回的字符串 
    int iLen=0; //需求改变的字符数 
    pszBig5=sBig.c_str(); //读入需求改换的字符参数 
    //计算转换的字符数 
    iLen=MultiByteToWideChar (950, 0, pszBig5, -1, NULL,0) ; 
    //给wszUnicode分配内存 
    wszUnicode=new wchar_t[iLen 1]; 
    //转换Big5码到Unicode码,使用了API函数MultiByteToWideChar 
    MultiByteToWideChar (950, 0, pszBig5, -1, wszUnicode,iLen); 
     //总计调换的字符数 
    iLen=WideCharToMultiByte (936, 0, (PWSTR) wszUnicode, -1, NULL,0, NULL, NULL) ; 
    //给pszGbt分配内部存款和储蓄器 
    pszGbt=new char[iLen 1]; 
    //给pszGbs分配内部存款和储蓄器 
    pszGbs=new char[iLen 1]; 
    //转换Unicode码到Gb码繁体,使用API函数WideCharToMultiByte 
    WideCharToMultiByte (936, 0, (PWSTR) wszUnicode, -1, pszGbt,iLen, NULL, NULL) ; 
    //调换Gb码繁体到Gb码简体,使用API函数LCMapString 
    LCMapString(0x0804,LCMAP_SIMPLIFIED_CHINESE, pszGbt, -1, pszGbs, iLen); 
    //再次回到Gb码简体字符 
    sGb=pszGbs; 
    //释放内部存款和储蓄器 
    delete [] wszUnicode; 
    delete [] pszGbt; 
    delete [] pszGbs; 
    return sGb; 
    } 
2   //--------------------------------------------------------------------------- 
//函数输入Gb字符,重回Big5字符**    //两遍调换*
    //--------------------------------------------------------------------------- 
    AnsiString __fastcall Gb2Big(AnsiString sGb) 
    { 
    char
 pszGbt=NULL; //Gb编码的繁体字符 
    char* pszGbs=NULL; //Gb编码的简体字符 
    wchar_t* wszUnicode=NULL; //Unicode编码的字符 
    char* pszBig5=NULL; //Big5编码的字符 
    AnsiString sBig5; //再次来到的字符串 
    int iLen=0; //须要转移的字符数 
    pszGbs=sGb.c_str(); //读入需求改换的字符参数 
    //计算转变的字符数 
    iLen=MultiByteToWideChar (936, 0, pszGbs, -1, NULL,0) ; 
    //给pszGbt分配内存 
    pszGbt=new char[iLen*2 1]; 
    //转变Gb码简体到Gb码繁体,使用API函数LCMapString 
LCMapString(0) 
要保证是在unicode情况下,才可选取WideCharToMultiByte

int size = ( length 1 ) * sizeof( wchar_t );

size正是unicode缓冲区的字节大小。

接下来大家调用Win API: MultiByteToWideChar(), 大概c库函数: mbstowcs(),把相关参数填入就能够。

一样,大家要将二个unicode转形成多字节串:

const wchar_t * str = L"1二3四";

该串wcslen求得长度是4,倘使我们就以(4 1)*2分配char空间,又浪费了,因为它实质上6 1个字节就可以存完。

就此,需求利用unicodeMinLength()。它将回来6。

int length = unicodeMinLength( str );

int size = ( length 1 ) * sizeof( char );

接下来我们调用Win API: WideCharToMultiByte(), 恐怕c库函数: wcstombs(),把有关参数填入就能够。

typedef bool Boolean, * PBoolean;
typedef char Char, * PChar;
typedef wchar_t WChar, * PWChar;
typedef unsigned char UChar, * PUChar, Byte, * PByte;
typedef short Short, * PShort;
typedef unsigned short UShort, * PUShort;
typedef int Int, * PInt;
typedef unsigned int UInt, * PUInt;
typedef long Long, * PLong;
typedef unsigned long ULong, * PULong;
typedef __int64 Int64, * PInt64;
typedef unsigned __int64 UInt64, * PUInt64;
typedef long long LongLong, * PLongLong;
typedef unsigned long long ULongLong, * PULongLong;
typedef double Double, * PDouble;
typedef float Float, * PFloat;
typedef Char const * PCSTR;
typedef WChar const * PCWSTR;
typedef Char * PSTR;
typedef WChar * PWSTR;

// 返回一个字符串里有多少个字符
Int ansiCharsCount( PCSTR ansiStr)
{
    Int count = 0;
    Char ch;
    while ( ch = *ansiStr )
    {
        if ( ch & (Byte)0x80 )
        {
            ansiStr  ;
        }
        count  ;
        ansiStr  ;
    }
    return count;
}
// 返回一个unicode字符串最少长度
Int unicodeMinLength( PCWSTR unicodeStr )
{
    Int size = 0;
    WChar ch;
    while ( ch = *unicodeStr )
    {
        if ( (UShort)ch > 0xFF )
        {
            size  ;
        }
        size  ;
        unicodeStr  ;
    }
    return size;
}
//该片段来自于http://outofmemory.cn

编辑:ca88 本文来源:multibyte和unicode互相调换时求长度的多个函数

关键词: 亚洲城ca88