c++string单双字符转换

commander-cpp:单头文件C++ CLI库的工业级实践 CLI(命令行接口)是C++系统工具开发的基础能力,其核心在于参数解析、帮助文档生成与类型安全校验。传统方案如getopt或boost::program_options常面临编译依赖重、文档与代码不同步、子命令管理复杂等工程痛点。commander-cpp以C++17现代特性为基石,通过单头文件实现零构建耦合,利用链式调用建模CLI语义层级,并在编译期完成帮助文本生成与类型反射,显著提升工业场景下的可维护性与确定性。它不仅简化了车载诊断、OTA升级等嵌入式CLI开发,更可作为跨协议(HTTP/gRPC/MQ 阅读详情

C++中各种string的相互转化


一 C++ 中 string与wstring互转

方法一:

string  WideToMutilByte( const  wstring &  _src)
{
int nBufSize = WideCharToMultiByte(GetACP(), 0, _src.c_str(),-1, NULL, 0, 0, FALSE);

char *szBuf = new char[nBufSize];

WideCharToMultiByte(GetACP(), 
0, _src.c_str(),-1, szBuf, nBufSize, 0, FALSE);

string strRet(szBuf);

delete []szBuf;
szBuf 
= NULL;

return strRet;
}


wstring MutilByteToWide(
const   string &  _src)
{
//计算字符串 string 转成 wchar_t 之后占用的内存字节数
int nBufSize = MultiByteToWideChar(GetACP(),0,_src.c_str(),-1,NULL,0); 

//为 wsbuf 分配内存 BufSize 个字节
wchar_t *wsBuf = new wchar_t[nBufSize];

//转化为 unicode 的 WideString
MultiByteToWideChar(GetACP(),0,_src.c_str(),-1,wsBuf,nBufSize); 

wstring wstrRet(wsBuf);

delete []wsBuf;
wsBuf 
= NULL;

return wstrRet;
}




转载:csdn

这篇文章里,我将给出几种C++ std::string和std::wstring相互转换的转换方法。
 
第一种方法:调用WideCharToMultiByte()和MultiByteToWideChar(),代码如下(关于详细的解释,可以参考《windows核心编程》):
 

#include  < string >
#include 
< windows.h >
using   namespace  std;
// Converting a WChar string to a Ansi string
std:: string  WChar2Ansi(LPCWSTR pwszSrc)
{
         
int nLen = WideCharToMultiByte(CP_ACP, 0, pwszSrc, -1, NULL, 0, NULL, NULL);
 
         
if (nLen<= 0) return std::string("");
 
         
char* pszDst = new char[nLen];
         
if (NULL == pszDst) return std::string("");
 
         WideCharToMultiByte(CP_ACP, 
0, pwszSrc, -1, pszDst, nLen, NULL, NULL);
         pszDst[nLen 
-1] = 0;
 
         std::
string strTemp(pszDst);
         delete [] pszDst;
 
         
return strTemp;
}


 
string  ws2s(wstring &  inputws)
{ 
        
return WChar2Ansi(inputws.c_str()); 
}



 
//Converting a Ansi string to WChar string 

std::wstring Ansi2WChar(LPCSTR pszSrc,  int  nLen)
 
{
    
int nSize = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pszSrc, nLen, 0, 0);
    
if(nSize <= 0) return NULL;
 
         WCHAR 
*pwszDst = new WCHAR[nSize+1];
    
if( NULL == pwszDst) return NULL;
 
    MultiByteToWideChar(CP_ACP, 
0,(LPCSTR)pszSrc, nLen, pwszDst, nSize);
    pwszDst[nSize] 
= 0;
 
    
if( pwszDst[0] == 0xFEFF)                    // skip Oxfeff
        for(int i = 0; i < nSize; i ++) 
                            pwszDst[i] 
= pwszDst[i+1]; 
 
    wstring wcharString(pwszDst);
         delete pwszDst;
 
    
return wcharString;
}


 
std::wstring s2ws(
const   string &  s)
{
     
return Ansi2WChar(s.c_str(),s.size());
}


  
 
第二种方法:采用ATL封装_bstr_t的过渡:(注,_bstr_是Microsoft Specific的,所以下面代码可以在VS2005通过,无移植性);

#include  < string >
#include 
< comutil.h >
using   namespace  std;
#pragma comment(lib, 
" comsuppw.lib " ) 
 
string  ws2s( const  wstring &  ws);
wstring s2ws(
const   string &  s);
 
string  ws2s( const  wstring &  ws)
{
         _bstr_t t 
= ws.c_str();
         
char* pchar = (char*)t;
         
string result = pchar;
         
return result;
}


 
wstring s2ws(
const   string &  s)
{
         _bstr_t t 
= s.c_str();
         wchar_t
* pwchar = (wchar_t*)t;
         wstring result 
= pwchar;
         
return result;
}


 
第三种方法:使用CRT库的mbstowcs()函数和wcstombs()函数,平台无关,需设定locale。

#include  < string >
#include 
< locale.h >
using   namespace  std;
string  ws2s( const  wstring &  ws)
{
         
string curLocale = setlocale(LC_ALL, NULL);        // curLocale = "C";
 
         setlocale(LC_ALL, 
"chs"); 
 
         
const wchar_t* _Source = ws.c_str();
         size_t _Dsize 
= 2 * ws.size() + 1;
         
char *_Dest = new char[_Dsize];
         memset(_Dest,
0,_Dsize);
         wcstombs(_Dest,_Source,_Dsize);
         
string result = _Dest;
         delete []_Dest;
 
         setlocale(LC_ALL, curLocale.c_str());
 
         
return result;
}


 
wstring s2ws(
const   string &  s)
{
         setlocale(LC_ALL, 
"chs"); 
 
         
const char* _Source = s.c_str();
         size_t _Dsize 
= s.size() + 1;
         wchar_t 
*_Dest = new wchar_t[_Dsize];
         wmemset(_Dest, 
0, _Dsize);
         mbstowcs(_Dest,_Source,_Dsize);
         wstring result 
= _Dest;
         delete []_Dest;
 
         setlocale(LC_ALL, 
"C");
 
         
return result;
}



二 utf8.utf16.utf32的相互转化

可以参考Unicode.org 上有ConvertUTF.c和ConvertUTF.h (下载地址: http://www.unicode.org/Public/PROGRAMS/CVTUTF/)

实现文件ConvertUTF.c:(.h省)
/*
 * Copyright 2001-2004 Unicode, Inc.
 * 
 * Disclaimer
 * 
 * This source code is provided as is by Unicode, Inc. No claims are
 * made as to fitness for any particular purpose. No warranties of any
 * kind are expressed or implied. The recipient agrees to determine
 * applicability of information provided. If this file has been
 * purchased on magnetic or optical media from Unicode, Inc., the
 * sole remedy for any claim will be exchange of defective media
 * within 90 days of receipt.
 * 
 * Limitations on Rights to Redistribute This Code
 * 
 * Unicode, Inc. hereby grants the right to freely use the information
 * supplied in this file in the creation of products supporting the
 * Unicode Standard, and to make copies of this file in any form
 * for internal or external distribution as long as this notice
 * remains attached.
 
*/


/* ---------------------------------------------------------------------

    Conversions between UTF32, UTF-16, and UTF-8. Source code file.
    Author: Mark E. Davis, 1994.
    Rev History: Rick McGowan, fixes & updates May 2001.
    Sept 2001: fixed const & error conditions per
    mods suggested by S. Parent & A. Lillich.
    June 2002: Tim Dodd added detection and handling of incomplete
    source sequences, enhanced error detection, added casts
    to eliminate compiler warnings.
    July 2003: slight mods to back out aggressive FFFE detection.
    Jan 2004: updated switches in from-UTF8 conversions.
    Oct 2004: updated to use UNI_MAX_LEGAL_UTF32 in UTF-32 conversions.

    See the header file "ConvertUTF.h" for complete documentation.

------------------------------------------------------------------------ 
*/



#include 
" ConvertUTF.h "
#ifdef CVTUTF_DEBUG
#include 
< stdio.h >
#endif

static   const   int  halfShift   =   10 ;  /* used for shifting by 10 bits */

static   const  UTF32 halfBase  =   0x0010000UL ;
static   const  UTF32 halfMask  =   0x3FFUL ;

#define  UNI_SUR_HIGH_START  (UTF32)0xD800
#define  UNI_SUR_HIGH_END    (UTF32)0xDBFF
#define  UNI_SUR_LOW_START   (UTF32)0xDC00
#define  UNI_SUR_LOW_END     (UTF32)0xDFFF
#define  false       0
#define  true        1

/* --------------------------------------------------------------------- */

ConversionResult ConvertUTF32toUTF16 (
    
const  UTF32 **  sourceStart,  const  UTF32 *  sourceEnd, 
    UTF16
**  targetStart, UTF16 *  targetEnd, ConversionFlags flags)  {
    ConversionResult result 
= conversionOK;
    
const UTF32* source = *sourceStart;
    UTF16
* target = *targetStart;
    
while (source < sourceEnd) {
    UTF32 ch;
    
if (target >= targetEnd) {
        result 
= targetExhausted; break;
    }

    ch 
= *source++;
    
if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */
        
/* UTF-16 surrogate values are illegal in UTF-32; 0xffff or 0xfffe are both reserved values */
        
if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
        
if (flags == strictConversion) {
            
--source; /* return to the illegal value itself */
            result 
= sourceIllegal;
            
break;
        }
 else {
            
*target++ = UNI_REPLACEMENT_CHAR;
        }

        }
 else {
        
*target++ = (UTF16)ch; /* normal case */
        }

    }
 else if (ch > UNI_MAX_LEGAL_UTF32) {
        
if (flags == strictConversion) {
        result 
= sourceIllegal;
        }
 else {
        
*target++ = UNI_REPLACEMENT_CHAR;
        }

    }
 else {
        
/* target is a character in range 0xFFFF - 0x10FFFF. */
        
if (target + 1 >= targetEnd) {
        
--source; /* Back up source pointer! */
        result 
= targetExhausted; break;
        }

        ch 
-= halfBase;
        
*target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START);
        
*target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START);
    }

    }

    
*sourceStart = source;
    
*targetStart = target;
    
return result;
}


/* --------------------------------------------------------------------- */

ConversionResult ConvertUTF16toUTF32 (
    
const  UTF16 **  sourceStart,  const  UTF16 *  sourceEnd, 
    UTF32
**  targetStart, UTF32 *  targetEnd, ConversionFlags flags)  {
    ConversionResult result 
= conversionOK;
    
const UTF16* source = *sourceStart;
    UTF32
* target = *targetStart;
    UTF32 ch, ch2;
    
while (source < sourceEnd) {
    
const UTF16* oldSource = source; /*  In case we have to back up because of target overflow. */
    ch 
= *source++;
    
/* If we have a surrogate pair, convert to UTF32 first. */
    
if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) {
        
/* If the 16 bits following the high surrogate are in the source buffer */
        
if (source < sourceEnd) {
        ch2 
= *source;
        
/* If it's a low surrogate, convert to UTF32. */
        
if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) {
            ch 
= ((ch - UNI_SUR_HIGH_START) << halfShift)
            
+ (ch2 - UNI_SUR_LOW_START) + halfBase;
            
++source;
        }
 else if (flags == strictConversion) { /* it's an unpaired high surrogate */
            
--source; /* return to the illegal value itself */
            result 
= sourceIllegal;
            
break;
        }

        }
 else { /* We don't have the 16 bits following the high surrogate. */
        
--source; /* return to the high surrogate */
        result 
= sourceExhausted;
        
break;
        }

    }
 else if (flags == strictConversion) {
        
/* UTF-16 surrogate values are illegal in UTF-32 */
        
if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) {
        
--source; /* return to the illegal value itself */
        result 
= sourceIllegal;
        
break;
        }

    }

    
if (target >= targetEnd) {
        source 
= oldSource; /* Back up source pointer! */
        result 
= targetExhausted; break;
    }

    
*target++ = ch;
    }

    
*sourceStart = source;
    
*targetStart = target;
#ifdef CVTUTF_DEBUG
if (result == sourceIllegal) {
    fprintf(stderr, 
"ConvertUTF16toUTF32 illegal seq 0x%04x,%04x/n", ch, ch2);
    fflush(stderr);
}

#endif
    
return result;
}


/* --------------------------------------------------------------------- */

/*
 * Index into the table below with the first byte of a UTF-8 sequence to
 * get the number of trailing bytes that are supposed to follow it.
 * Note that *legal* UTF-8 values can't have 4 or 5-bytes. The table is
 * left as-is for anyone who may want to do such conversion, which was
 * allowed in earlier algorithms.
 
*/

static   const   char  trailingBytesForUTF8[ 256 ]  =   {
    
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
    
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5
}
;

/*
 * Magic values subtracted from a buffer value during UTF8 conversion.
 * This table contains as many values as there might be trailing bytes
 * in a UTF-8 sequence.
 
*/

static   const  UTF32 offsetsFromUTF8[ 6 ]  =   { 0x00000000UL, 0x00003080UL, 0x000E2080UL, 
             
0x03C82080UL, 0xFA082080UL, 0x82082080UL }
;

/*
 * Once the bits are split out into bytes of UTF-8, this is a mask OR-ed
 * into the first byte, depending on how many bytes follow.  There are
 * as many entries in this table as there are UTF-8 sequence types.
 * (I.e., one byte sequence, two byte etc.). Remember that sequencs
 * for *legal* UTF-8 will be 4 or fewer bytes total.
 
*/

static   const  UTF8 firstByteMark[ 7 ]  =   { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC } ;

/* --------------------------------------------------------------------- */

/* The interface converts a whole buffer to avoid function-call overhead.
 * Constants have been gathered. Loops & conditionals have been removed as
 * much as possible for efficiency, in favor of drop-through switches.
 * (See "Note A" at the bottom of the file for equivalent code.)
 * If your compiler supports it, the "isLegalUTF8" call can be turned
 * into an inline function.
 
*/


/* --------------------------------------------------------------------- */

ConversionResult ConvertUTF16toUTF8 (
    
const  UTF16 **  sourceStart,  const  UTF16 *  sourceEnd, 
    UTF8
**  targetStart, UTF8 *  targetEnd, ConversionFlags flags)  {
    ConversionResult result 
= conversionOK;
    
const UTF16* source = *sourceStart;
    UTF8
* target = *targetStart;
    
while (source < sourceEnd) {
    UTF32 ch;
    unsigned 
short bytesToWrite = 0;
    
const UTF32 byteMask = 0xBF;
    
const UTF32 byteMark = 0x80; 
    
const UTF16* oldSource = source; /* In case we have to back up because of target overflow. */
    ch 
= *source++;
    
/* If we have a surrogate pair, convert to UTF32 first. */
    
if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) {
        
/* If the 16 bits following the high surrogate are in the source buffer */
        
if (source < sourceEnd) {
        UTF32 ch2 
= *source;
        
/* If it's a low surrogate, convert to UTF32. */
        
if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) {
            ch 
= ((ch - UNI_SUR_HIGH_START) << halfShift)
            
+ (ch2 - UNI_SUR_LOW_START) + halfBase;
            
++source;
        }
 else if (flags == strictConversion) { /* it's an unpaired high surrogate */
            
--source; /* return to the illegal value itself */
            result 
= sourceIllegal;
            
break;
        }

        }
 else { /* We don't have the 16 bits following the high surrogate. */
        
--source; /* return to the high surrogate */
        result 
= sourceExhausted;
        
break;
        }

    }
 else if (flags == strictConversion) {
        
/* UTF-16 surrogate values are illegal in UTF-32 */
        
if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) {
        
--source; /* return to the illegal value itself */
        result 
= sourceIllegal;
        
break;
        }

    }

    
/* Figure out how many bytes the result will require */
    
if (ch < (UTF32)0x80) {         bytesToWrite = 1;
    }
 else if (ch < (UTF32)0x800) {     bytesToWrite = 2;
    }
 else if (ch < (UTF32)0x10000) {   bytesToWrite = 3;
    }
 else if (ch < (UTF32)0x110000) {  bytesToWrite = 4;
    }
 else {                bytesToWrite = 3;
                        ch 
= UNI_REPLACEMENT_CHAR;
    }


    target 
+= bytesToWrite;
    
if (target > targetEnd) {
        source 
= oldSource; /* Back up source pointer! */
        target 
-= bytesToWrite; result = targetExhausted; break;
    }

    
switch (bytesToWrite) { /* note: everything falls through. */
        
case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
        
case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
        
case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
        
case 1: *--target =  (UTF8)(ch | firstByteMark[bytesToWrite]);
    }

    target 
+= bytesToWrite;
    }

    
*sourceStart = source;
    
*targetStart = target;
    
return result;
}


/* --------------------------------------------------------------------- */

/*
 * Utility routine to tell whether a sequence of bytes is legal UTF-8.
 * This must be called with the length pre-determined by the first byte.
 * If not calling this from ConvertUTF8to*, then the length can be set by:
 *  length = trailingBytesForUTF8[*source]+1;
 * and the sequence is illegal right away if there aren't that many bytes
 * available.
 * If presented with a length > 4, this returns false.  The Unicode
 * definition of UTF-8 goes up to 4-byte sequences.
 
*/


static  Boolean isLegalUTF8( const  UTF8  * source,  int  length)  {
    UTF8 a;
    
const UTF8 *srcptr = source+length;
    
switch (length) {
    
default: return false;
    
/* Everything else falls through when "true" */
    
case 4: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false;
    
case 3: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false;
    
case 2: if ((a = (*--srcptr)) > 0xBF) return false;

    
switch (*source) {
        
/* no fall-through in this inner switch */
        
case 0xE0: if (a < 0xA0) return false; break;
        
case 0xED: if (a > 0x9F) return false; break;
        
case 0xF0: if (a < 0x90) return false; break;
        
case 0xF4: if (a > 0x8F) return false; break;
        
default:   if (a < 0x80) return false;
    }


    
case 1: if (*source >= 0x80 && *source < 0xC2) return false;
    }

    
if (*source > 0xF4) return false;
    
return true;
}


/* --------------------------------------------------------------------- */

/*
 * Exported function to return whether a UTF-8 sequence is legal or not.
 * This is not used here; it's just exported.
 
*/

Boolean isLegalUTF8Sequence(
const  UTF8  * source,  const  UTF8  * sourceEnd)  {
    
int length = trailingBytesForUTF8[*source]+1;
    
if (source+length > sourceEnd) {
    
return false;
    }

    
return isLegalUTF8(source, length);
}


/* --------------------------------------------------------------------- */

ConversionResult ConvertUTF8toUTF16 (
    
const  UTF8 **  sourceStart,  const  UTF8 *  sourceEnd, 
    UTF16
**  targetStart, UTF16 *  targetEnd, ConversionFlags flags)  {
    ConversionResult result 
= conversionOK;
    
const UTF8* source = *sourceStart;
    UTF16
* target = *targetStart;
    
while (source < sourceEnd) {
    UTF32 ch 
= 0;
    unsigned 
short extraBytesToRead = trailingBytesForUTF8[*source];
    
if (source + extraBytesToRead >= sourceEnd) {
        result 
= sourceExhausted; break;
    }

    
/* Do this check whether lenient or strict */
    
if (! isLegalUTF8(source, extraBytesToRead+1)) {
        result 
= sourceIllegal;
        
break;
    }

    
/*
     * The cases all fall through. See "Note A" below.
     
*/

    
switch (extraBytesToRead) {
        
case 5: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */
        
case 4: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */
        
case 3: ch += *source++; ch <<= 6;
        
case 2: ch += *source++; ch <<= 6;
        
case 1: ch += *source++; ch <<= 6;
        
case 0: ch += *source++;
    }

    ch 
-= offsetsFromUTF8[extraBytesToRead];

    
if (target >= targetEnd) {
        source 
-= (extraBytesToRead+1); /* Back up source pointer! */
        result 
= targetExhausted; break;
    }

    
if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */
        
/* UTF-16 surrogate values are illegal in UTF-32 */
        
if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
        
if (flags == strictConversion) {
            source 
-= (extraBytesToRead+1); /* return to the illegal value itself */
            result 
= sourceIllegal;
            
break;
        }
 else {
            
*target++ = UNI_REPLACEMENT_CHAR;
        }

        }
 else {
        
*target++ = (UTF16)ch; /* normal case */
        }

    }
 else if (ch > UNI_MAX_UTF16) {
        
if (flags == strictConversion) {
        result 
= sourceIllegal;
        source 
-= (extraBytesToRead+1); /* return to the start */
        
break; /* Bail out; shouldn't continue */
        }
 else {
        
*target++ = UNI_REPLACEMENT_CHAR;
        }

    }
 else {
        
/* target is a character in range 0xFFFF - 0x10FFFF. */
        
if (target + 1 >= targetEnd) {
        source 
-= (extraBytesToRead+1); /* Back up source pointer! */
        result 
= targetExhausted; break;
        }

        ch 
-= halfBase;
        
*target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START);
        
*target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START);
    }

    }

    
*sourceStart = source;
    
*targetStart = target;
    
return result;
}


/* --------------------------------------------------------------------- */

ConversionResult ConvertUTF32toUTF8 (
    
const  UTF32 **  sourceStart,  const  UTF32 *  sourceEnd, 
    UTF8
**  targetStart, UTF8 *  targetEnd, ConversionFlags flags)  {
    ConversionResult result 
= conversionOK;
    
const UTF32* source = *sourceStart;
    UTF8
* target = *targetStart;
    
while (source < sourceEnd) {
    UTF32 ch;
    unsigned 
short bytesToWrite = 0;
    
const UTF32 byteMask = 0xBF;
    
const UTF32 byteMark = 0x80; 
    ch 
= *source++;
    
if (flags == strictConversion ) {
        
/* UTF-16 surrogate values are illegal in UTF-32 */
        
if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
        
--source; /* return to the illegal value itself */
        result 
= sourceIllegal;
        
break;
        }

    }

    
/*
     * Figure out how many bytes the result will require. Turn any
     * illegally large UTF32 things (> Plane 17) into replacement chars.
     
*/

    
if (ch < (UTF32)0x80) {         bytesToWrite = 1;
    }
 else if (ch < (UTF32)0x800) {     bytesToWrite = 2;
    }
 else if (ch < (UTF32)0x10000) {   bytesToWrite = 3;
    }
 else if (ch <= UNI_MAX_LEGAL_UTF32) {  bytesToWrite = 4;
    }
 else {                bytesToWrite = 3;
                        ch 
= UNI_REPLACEMENT_CHAR;
                        result 
= sourceIllegal;
    }

    
    target 
+= bytesToWrite;
    
if (target > targetEnd) {
        
--source; /* Back up source pointer! */
        target 
-= bytesToWrite; result = targetExhausted; break;
    }

    
switch (bytesToWrite) { /* note: everything falls through. */
        
case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
        
case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
        
case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
        
case 1: *--target = (UTF8) (ch | firstByteMark[bytesToWrite]);
    }

    target 
+= bytesToWrite;
    }

    
*sourceStart = source;
    
*targetStart = target;
    
return result;
}


/* --------------------------------------------------------------------- */

ConversionResult ConvertUTF8toUTF32 (
    
const  UTF8 **  sourceStart,  const  UTF8 *  sourceEnd, 
    UTF32
**  targetStart, UTF32 *  targetEnd, ConversionFlags flags)  {
    ConversionResult result 
= conversionOK;
    
const UTF8* source = *sourceStart;
    UTF32
* target = *targetStart;
    
while (source < sourceEnd) {
    UTF32 ch 
= 0;
    unsigned 
short extraBytesToRead = trailingBytesForUTF8[*source];
    
if (source + extraBytesToRead >= sourceEnd) {
        result 
= sourceExhausted; break;
    }

    
/* Do this check whether lenient or strict */
    
if (! isLegalUTF8(source, extraBytesToRead+1)) {
        result 
= sourceIllegal;
        
break;
    }

    
/*
     * The cases all fall through. See "Note A" below.
     
*/

    
switch (extraBytesToRead) {
        
case 5: ch += *source++; ch <<= 6;
        
case 4: ch += *source++; ch <<= 6;
        
case 3: ch += *source++; ch <<= 6;
        
case 2: ch += *source++; ch <<= 6;
        
case 1: ch += *source++; ch <<= 6;
        
case 0: ch += *source++;
    }

    ch 
-= offsetsFromUTF8[extraBytesToRead];

    
if (target >= targetEnd) {
        source 
-= (extraBytesToRead+1); /* Back up the source pointer! */
        result 
= targetExhausted; break;
    }

    
if (ch <= UNI_MAX_LEGAL_UTF32) {
        
/*
         * UTF-16 surrogate values are illegal in UTF-32, and anything
         * over Plane 17 (> 0x10FFFF) is illegal.
         
*/

        
if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
        
if (flags == strictConversion) {
            source 
-= (extraBytesToRead+1); /* return to the illegal value itself */
            result 
= sourceIllegal;
            
break;
        }
 else {
            
*target++ = UNI_REPLACEMENT_CHAR;
        }

        }
 else {
        
*target++ = ch;
        }

    }
 else { /* i.e., ch > UNI_MAX_LEGAL_UTF32 */
        result 
= sourceIllegal;
        
*target++ = UNI_REPLACEMENT_CHAR;
    }

    }

    
*sourceStart = source;
    
*targetStart = target;
    
return result;
}


/* ---------------------------------------------------------------------

    Note A.
    The fall-through switches in UTF-8 reading code save a
    temp variable, some decrements & conditionals.  The switches
    are equivalent to the following loop:
    {
        int tmpBytesToRead = extraBytesToRead+1;
        do {
        ch += *source++;
        --tmpBytesToRead;
        if (tmpBytesToRead) ch <<= 6;
        } while (tmpBytesToRead > 0);
    }
    In UTF-8 writing code, the switches on "bytesToWrite" are
    similarly unrolled loops.

   --------------------------------------------------------------------- 
*/




三 C++ 的字符串与C#的转化

1)将system::String 转化为C++的string:
//  convert_system_string.cpp
//  compile with: /clr
#include  < string >
#include 
< iostream >
using   namespace  std;
using   namespace  System;

void  MarshalString ( String  ^  s,  string &  os )  {
   
using namespace Runtime::InteropServices;
   
const char* chars = 
      (
const char*)(Marshal::StringToHGlobalAnsi(s)).ToPointer();
   os 
= chars;
   Marshal::FreeHGlobal(IntPtr((
void*)chars));
}


void  MarshalString ( String  ^  s, wstring &  os )  {
   
using namespace Runtime::InteropServices;
   
const wchar_t* chars = 
      (
const wchar_t*)(Marshal::StringToHGlobalUni(s)).ToPointer();
   os 
= chars;
   Marshal::FreeHGlobal(IntPtr((
void*)chars));
}


int  main()  {
   
string a = "test";
   wstring b 
= L"test2";
   String 
^ c = gcnew String("abcd");

   cout 
<< a << endl;
   MarshalString(c, a);
   c 
= "efgh";
   MarshalString(c, b);
   cout 
<< a << endl;
   wcout 
<< b << endl;
}



2)将System::String转化为char*或w_char*
//  convert_string_to_wchar.cpp
//  compile with: /clr
#include  <  stdio.h  >
#include 
<  stdlib.h  >
#include 
<  vcclr.h  >

using   namespace  System;

int  main()  {
   String 
^str = "Hello";

   
// Pin memory so GC can't move it while native function is called
   pin_ptr<const wchar_t> wch = PtrToStringChars(str);
   printf_s(
"%S/n", wch);

   
// Conversion to char* :
   
// Can just convert wchar_t* to char* using one of the 
   
// conversion functions such as: 
   
// WideCharToMultiByte()
   
// wcstombs_s()
   
//  etc
   size_t convertedChars = 0;
   size_t  sizeInBytes 
= ((str->Length + 1) * 2);
   errno_t err 
= 0;
   
char    *ch = (char *)malloc(sizeInBytes);

   err 
= wcstombs_s(&convertedChars, 
                    ch, sizeInBytes,
                    wch, sizeInBytes);
   
if (err != 0)
      printf_s(
"wcstombs_s  failed!/n");

    printf_s(
"%s/n", ch);
}
 
C++字符转换 本文探讨了UTF-8与GBK编码的转换问题,重点分析了Windows和Linux平台下wchar_t的差异(Windows使用UTF-16,Linux使用UTF-32)。提供了多种编码转换方案:1)使用Windows API函数MultiByteToWideChar和WideCharToMultiByte实现UTF-8与GBK互转;2)通过ASCII/Unicode/UTF-8中间转换实现编码转换;3)利用ATL封装的_bstr_t进行字符串转换;4)使用跨平台的iconv库。 阅读详情

相关推荐

脑机接口(BCI)从原理到开发实战 07|运动想象BCI实战:基于BCI Competition IV 2a数据集

本文基于BCI Competition IV 2a数据集,详细介绍运动想象脑机接口系统的全流程实现。首先概述了该数据集的实验范式、参数特点和优势,然后指导环境准备与数据下载。通过代码示例展示了数据加载、事件标记提取和信号可视化方法。重点构建了完整的预处理流水线,包括通道选择、重参考、带通滤波(8-30Hz)和ICA去伪迹等关键步骤。文章旨在帮助读者将零散的BCI知识整合为完整的实战项目,掌握从原始脑电数据到运动意图解码的核心技术。

小明的博客 848

C++ wstring和string相互转换的几种方法

方式一:采用ATL封装_bstr_t的过渡 #include &lt;comutil.h&gt; #pragma comment(lib, "comsuppw.lib") string wstring2string(const wstring&amp; ws) { _bstr_t t = ws.c_str(); char* pchar = (char*)t; ...

mercy_ps的博客 2万+

从翼型到湍流:用生活化案例图解空气动力学核心概念(中英双语版)

本文通过飞机机翼、F1赛车、高尔夫球等生活化案例,图解空气动力学核心概念。深入浅出地解释了攻角如何产生升力、边界层与流动分离如何影响阻力、马赫数如何划分速度世界,以及涡流与湍流的特性与应用。文章还介绍了计算流体动力学(CFD)这一现代数字风洞工具,帮助读者直观理解这些塑造现代交通与运动设计的无形之力。

metaverse5vr的博客 475

c++string单双字符转换。。。。。。

C++中各种string的相互转化 一 C++ 中 string与wstring互转方法一:string WideToMutilByte(const wstring& _src){int nBufSize = WideCharToMultiByte(GetACP(), 0, _src.c_str(),-1, NULL, 0, 0, FALSE);char *szBuf = new char

天蓝的专栏 3923

寒假实训笔记day01——认识M4单片机之STM32F405RGT6

认识M4单片机之STM32F405RGT6(含义、规格、参数)

weixin_47200070的博客 8551

单点DToF激光测距传感器各家产品的比较

汇总DToF 单点测距传感器的相关信息

Linux 设备驱动概述及开发环境构建 (一) 1772

C++string与wstring类型转换

在c++开发时有的库函数必须传递wstring宽字符串作为参数,在代码中通过L"wstring"定义宽字符串传递参数这没什么难度,问题是实际过程中需要接收输入string数据,这时候就需要将string转换为wstring。

qq_30386941的博客 8247

直捣黄龙~

这篇文章描述了一个矩阵寻路问题,要求计算从起点到终点的最短路径数量及长度。主要思路是通过BFS算法解决:首先标记哨兵警戒区域为禁区,然后从起点出发进行广度优先搜索,记录每个位置的最短步数和路径条数。当到达终点时,输出路径数和步数;若不可达则返回(0,0)。算法使用队列实现BFS,同时处理路径统计和步数记录,适用于网格寻路类问题。

面试高手的博客 216

c++_string和wstring的相互转换

string是常用类型,可以看作char[]。而wstring,使用的是wchar_t类型,这是宽字符,用于满足非ASCII字符的要求,例如Unicode编码,中文,日文,韩文什么的。wstring是宽字符,占用2个字节的大小,针对UNICODE编码格式,用于对中文汉字的定义和赋值。也就是说,宽字符,每表示一个字符其实是占了16bit,即2个char的大小。1、wstring:wstring是宽字符,占用2个字节的大小,即16bit。2、string:string是窄字符,占用1个字节的大小,即8bit。

9分钟带帽 6669

基于 STM32 的智慧农业温室控制系统设计与实现

本文提出一种基于 STM32 微控制器的智慧农业温室控制系统设计方案,通过集成多类型环境传感器、执行机构及无线通信模块,实现对温室内温湿度、光照、土壤湿度等参数的实时监测与自动调控。文中详细阐述硬件选型、电路连接及软件实现流程,并附关键代码示例,为智慧农业领域提供低成本、高可靠性的温室控制解决方案。

weixin_42300449的博客 1923

2026最新openclaw(clawbot/moltbot)真正在自己个人电脑上搭建部署,配置飞书远程远程让AI助理操控电脑完成任务,以及结合ollama无限token实现7*24小时工作(附配置)

2026最新openclaw(clawbot/moltbot)真正在自己个人电脑上搭建部署,配置飞书远程远程让AI助理操控电脑完成任务,以及结合 ollama 无限token实现7*24小时工作,以及部署安装需要的 skills 完成复杂的工作任务(附完整可以运行的配置文件)。 很多人已经会配置安装 openclaw 了 ,但是 安装完成之后真正让电脑自动运行起来的很好,完成出色工作的更少,最常见的就是聊聊天,或者执行一些简单的命令,理解要让电脑自动化工作,openclaw、skills、大模型这三样。

代码讲故事 2962

wchar_t*和string相互转换

在处理中文时,一个中文通常占用2个字节,而char*和string字符串中的字符都是一个字节的,为了能够有效处理中文,引入了wchar_t*型变量,当需要处理中文时,可以首先将string转换成char*,然后将char*转换成wchar_t*即可。 在window环境中,可以利用 MultiByteToWideChar(); WideCharToMultiByte(); 两个API函数来实

一个程序渣渣的小后院 2万+

复旦微FMSH_Procise安装全流程详解:从环境配置到实战避坑指南

通过本文的全流程解析+实战技巧,开发者可快速掌握Procise在复旦微芯片开发中的核心应用。未来随着AKConv轻量级架构(参考往期文章)等创新技术的融入,国产芯片开发生态将更加完善。立即关注本专栏,获取最新多镜像切换指南与Linux SDK实战教程!扩展阅读复旦微在线升级BOOT.BIN全解析H7-TOOL实现复旦微脱机烧录(注:本文实验环境为Windows 10 x64 + FMQL45T-CORE开发板,部分操作可能因版本更新调整)立即行动下载本文配套配置文件:[GitHub链接]加入技术交流群。

QQ_778132974的博客 3237

C++把一个字符转换成string方法

C++把一个字符转换成string方法 原网址:https://zhidao.baidu.com/question/492029810.html 单个字符无法直接转换为string 间接的方式有以下两种: 1.先将字符写在字符数组中,再用字符数组赋值给string #include <iostream> #include <string> using namespace std; int main() { char ch = 'x'; string s ;

qq_44709990的博客 4469

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

C++把一个字符转换成string方法.

1 先将字符写在字符数组中,再用字符数组赋值给string. 参考代码如下: #include &lt;iostream&gt; #include &lt;string&gt; using namespace std; int main() {     char ch = 'X';     string s ;     char s1[2] = {ch, 0};//定义一个字符数组,即传统的...

moonlightpeng的博客 1万+

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

C++ 中将 Char 转换成 String

@TOC 概览 使用 string::string(size_type count, charT ch) 构造器 使用 push_back() 使用append() 使用 insert() 使用string::string(size_type count, charT ch)构造函数将字符转换为字符串 此方法使用std::string的构造函数,为 C++ 中的字符串对象转换字符。构造函数有两个参数:一个count值,它是一个新字符串将包含的字符数,以及一个char分配给每个字符的值。请注意,此方法定

qq_45936312的博客 1万+

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

C++各种字符转换

字符串转换

嵌入式与人工智能 2029

c++ 字符转换

c++ 字符转换 CString 转换成string 我试了很多的方法,都不行,我用的vs2010 ------解决方案-------------------- unicode: CString sz1 = L"abc"; std::string sz2 = CT2A(sz1.GetBuffer()); //转化为非unicode. 非unicode: CString sz1 = “abc”; std::string sz2 = sz1.GetBuffer(); ------解决方案------------

weixin_44322778的博客 2210

C++string类型详解

我们知道string可以构造一个字符串变量,那么它的操作有哪些呢。它包含在string库中(不是string.h没有.h),它可以和定义一个字符一样定义一个字符串变量,而且强大的C++还内置了各种函数,基本实现不用再手写操作函数。而且可以进行字典序的比较和串操作。 一、对位和对串操作 如何或者string串中的某一位字符呢,我们使用数组下面的方式就可以访问。 例如 string s = "abcdef"; cout << s[0] << endl; 结果就应该是输出了字符’a’,同

芒种、的博客 2523

c++转换char为string的几种方式

使用string构造函数 构造函数 std::string(size_t n, char c);使用n个字符c初始化string对象。 char c = '1'; std::string s(1, c); std::cout << s << std::endl; 使用stringstream stringstream能够在string和其他数据类型之间进行...

guotianqing的博客 1万+

c++ string 无法通过下标访问_C++ string

1.[]和at()的区别在于[]不检查索引是否有效,而at()在遇到无效索引时会抛出out_of_range异常.下标[]赋值会显示SIGSEGV段错误,越界错误.at赋值会显示 terminate called after throwing an instance of ‘std::out_of_range’2.string类型 s[i] 返回值是 char类型的引用,而不是 string类型3...

weixin_39822673的博客 1350

[GESP202606 三级] 字符转换

这篇文章摘要聚焦于GESP C++三级考试中的字符转换类题目,整合了多个视频讲解资源(B站)和文字题解(优快云),涵盖知识点如字符串处理、进制转换、位运算等核心考点。相关链接包括真题解析、集训课程、知识点速通及数学/信奥学习资料推荐,适用于备考学生系统复习三级内容。同时扩展了信息学竞赛数学基础、省选题单和NOI相关学习资源,形成完整的训练体系。

青少年趣味编程 54

C++ string实现原理

C++程序员编码过程中经常会使用string(wstring)类,你是否思考过它的内部实现细节。比如这个类的迭代器是如何实现的?对象占多少字节的内存空间?内部有没有虚函数?内存是如何分配的?

passion_wu128的专栏 1万+

将int、char型字符转换为String

string string 是 C++ 提供的字串型態,和 C 的字串相比,除了有不限长度的优点外,还有其他许多方便的功能。要使用 string, 必須先加入这一行: #include 接下來要宣告一个字串变量,可以写成: string s; 我们也可以在宣告的同时让它设成某个字串: string s="TCGS"; 而要取得其中某一個字元,和传统C 的字串一樣是用 s[i] 

sinat_24520925的专栏 2145

C++字符串std::string

https://blog.youkuaiyun.com/SavitarYu/article/details/81029676 https://blog.youkuaiyun.com/qq_38877888/article/details/104010047

qq_43148810的博客 1474

C++字符串拼接与字符转换:性能优化与工程实践指南

字符串处理是编程中的基础操作,其核心原理在于内存中字符序列的组织与管理。在C++中,字符串通常以std::string类或C风格字符数组的形式存在,前者自动管理内存,后者需要手动处理。理解字符串在内存中的表示方式,有助于选择高效的操作方法。从技术价值看,合理的字符串操作能显著提升程序性能,避免不必要的内存分配与拷贝。在实际应用场景中,字符串拼接与转换广泛用于日志记录、数据序列化、网络通信等领域。本文聚焦于C++中的字符转字符串与字符串拼接操作,深入探讨了std::string的append方法、reserv

weixin_32175665的博客 280
上一篇: 字符串转换_BSTR/LPSTR/LPWSTR/Char
下一篇: (转)Visual C++ 如何:在各种字符串类型之间进行转换
lightyearwp
博客等级 码龄20年 16粉丝 37原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值