C++ wstring string char* wchar_t相互转换


转:C++ wstring string char* wchar_t相互转换

转自:http://blog.csdn.net/tobefxz/article/details/17405961

 

1. char*->string

(1)直接转换

const char* nodename;
string temp = nodename;
string temp2(nodename);

2. wchar_t*->wstring

(1)直接转换

const wchar_t* nodename;
wstring temp = nodename;
wstring temp2(nodename);

3. string->char*

   wstring->char*

方法一:

(1)将wstring.c_str()转为wchar_t*

方法二:

(1)将string.c_str(), wstring.c_str()转为AnsiString(http://blog.csdn.net/bannico/article/details/7577728),

(2)将AnsiString.c_str()转为char*

复制代码
方法一:
string temp;
const char* nodename = temp.c_str();
方法二:
struct IPAddress{ std::wstring hostname; std::vector<std::wstring> ips; }; scripting::IPAddress dns = (*pPreloadDns)[i]; AnsiString strA = dns.hostname.c_str(); char * hn = strA.c_str();
复制代码

但据说这样很不可靠(http://bbs.csdn.net/topics/30479944),安全的做法是:

方法三:
String str="123456"; int len=str.Length(); char *cp=new char[len+1]; StrPCopy(cp, str);

4. wstring->wchar_t*

    string->w_char*(参见5)

方法一:

(1)将wstring.c_str()转为wchar_t*

方法二.一:

(1)将wstring.c_str()转为UnicodeString 

(2)将UnicodeString.c_str()转为wchar_t*

方法二.二:

(1)将wstring.c_str()转为AnsiString 

(2)使用ANSIToUnicode方法将AnsiString.c_str()转为wchar_t*

复制代码
方法一:
wstring temp;
wchar_t* nodename = temp.c_str();
方法二.一:
struct IPAddress{
    std::wstring hostname;
    std::vector<std::wstring> ips;
};

scripting::IPAddress dns = (*pPreloadDns)[i];
UnicodeString strA = dns.hostname.c_str();
//char * hn = strA.c_str();
wchar_t * hn = strA.c_str();

方法二.二:
struct IPAddress{
    std::wstring hostname;
    std::vector<std::wstring> ips;
};

scripting::IPAddress dns = (*pPreloadDns)[i];
AnsiString strA = dns.hostname.c_str();
//char * hn = strA.c_str();
wchar_t * hn = ANSIToUnicode(strA.c_str());
复制代码

5. char*->UnicodeString->wstring, wchar_t*

(1)将char*转为UnicodeString

(2)将UnicodeString.c_str()转为wstring, wchar_t*

UnicodeString temp(inet_ntoa(pAddr->sin_addr)) ; //inet_ntoa returns char*
std::wstring addr(temp.c_str());
wchar_t* addr2 = temp.c_str();
log_debug(_T("set connection ip:") << addr); con->setIP(addr);

6. wchar_t*->AnsiString->string, char*

(1)将wchar_t*转为AnsiString

(2)将AnsiString.c_str()转为string, char*

wchar_t* str = wstring.c_str();
AnsiString temp(str ) ; //inet_ntoa returns char*
std::string addr(temp.c_str());
char* addr2 = temp.c_str();
log_debug(_T("set connection ip:") << addr); con->setIP(addr);

下面关于string,wstring互转的方法是错误的。对ansi字符可能能得到正确结果,但如果传入的参数是“中文”字符串,将得不到正确的结果。

 7. string->wstring 

复制代码
static wstring Str2Wstr (string str )
{
    if (str.length() == 0)
        return L"";

    std::wstring wstr;
    wstr.assign (str.begin(), str.end());
    return wstr;
}
复制代码

 8. wstring->string

复制代码
static string Wstr2Str(wstring wstr )
{
    if (wstr.length() == 0)
        return "";

    std::string str;
    str.assign (wstr.begin(), wstr.end());
    return str;
}
复制代码

 正确的做法是使用MultiByteToWideChar和WideCharToMultiByte:

9. string->wstring

复制代码
std::wstring stringToWstring(const std::string& str)
{
    LPCSTR pszSrc = str.c_str();
    int nLen = MultiByteToWideChar(CP_ACP, 0, pszSrc, -1, NULL, 0);
    if (nLen == 0) 
        return std::wstring(L"");

    wchar_t* pwszDst = new wchar_t[nLen];
    if (!pwszDst) 
        return std::wstring(L"");

    MultiByteToWideChar(CP_ACP, 0, pszSrc, -1, pwszDst, nLen);
    std::wstring wstr(pwszDst);
    delete[] pwszDst;
    pwszDst = NULL;

    return wstr;
}
复制代码

10. wstring->string

复制代码
std::string wstringToString(const std::wstring& wstr)
{
    LPCWSTR pwszSrc = wstr.c_str();
    int nLen = WideCharToMultiByte(CP_ACP, 0, pwszSrc, -1, NULL, 0, NULL, NULL);
    if (nLen == 0) 
        return std::string("");

    char* pszDst = new char[nLen];
    if (!pszDst) 
        return std::string("");

    WideCharToMultiByte(CP_ACP, 0, pwszSrc, -1, pszDst, nLen, NULL, NULL);
    std::string str(pszDst);
    delete[] pszDst;
    pszDst = NULL;

    return str;
}
复制代码

测试代码:

复制代码
int _tmain(int argc, _TCHAR* argv[])
{
    std::string str = "中文";
    std::wstring wstr = L"中文";
    std::string str1 = "";
    std::wstring wstr1 = L"";
    LPCSTR pSrc = "中文";
    LPCWSTR pwzSrc = L"中文";

    stringToWstring(str);
    wstringToString(wstr);
    stringToWstring(str1);
    wstringToString(wstr1);
    stringToWstring(pSrc);
    wstringToString(pwzSrc);

    return 0;
}
复制代码

 

Original URL: http://www.cnblogs.com/zhcncn/archive/2013/05/20/3089084.html

 

wstring与string相互转换

转自:http://www.cnblogs.com/SunboyL/archive/2013/03/31/stringandwstring.html

 1 #include <string>
 2 #include <locale.h> 
 3 
 4 // 需包含locale、string头文件、使用setlocale函数。
 5 std::wstring StringToWstring(const std::string str)
 6 {// string转wstring
 7     unsigned len = str.size() * 2;// 预留字节数
 8     setlocale(LC_CTYPE, "");     //必须调用此函数
 9     wchar_t *p = new wchar_t[len];// 申请一段内存存放转换后的字符串
10     mbstowcs(p,str.c_str(),len);// 转换
11     std::wstring str1(p);
12     delete[] p;// 释放申请的内存
13     return str1;
14 }
15 
16 std::string WstringToString(const std::wstring str)
17 {// wstring转string
18     unsigned len = str.size() * 4;
19     setlocale(LC_CTYPE, "");
20     char *p = new char[len];
21     wcstombs(p,str.c_str(),len);
22     std::string str1(p);
23     delete[] p;
24     return str1;
25 }
26 
27 
28 int main()
29 {
30     std::string str = "我是SunboyL。";
31     std::wstring str1 = StringToWstring(str);// string转换为wstring
32     
33     str1 = L"我是不是SunboyL。";
34     str = WstringToString(str1);// wstring转换为string
35     return 0;
36 }
View Code

 

VS2005:C++ std::string, std::wstring转换方法(转)

转自:http://blog.sina.com.cn/s/blog_700a65cc0100migm.html

随着 VS2003升级到VS2005,很多以前熟悉的输入输出方式以及参数传递方式都不再有效(参看vs2003 到vs2005代码升级要点)。其中根字符串相关的内容是,wcout不再有效,默认参数传递方式由char*改成了wchar_t*等几个方面。为了解决上面的这些问题,这篇文章里,我将给出几种C++ std::string和std::wstring相互转换的转换方法。

第0种方法,更新于(2009年3月22):好久不用windows,好久不用VS.net了。今天网上查找资料,看到下述实现,记录未验证。(抽空去验证了一下,这个,好像对中文无效...)

std::wstring s2ws(const std::string& s)
{
    std::wstring temp(s.length(),L‘ ‘);
    std::copy(s.begin(), s.end(), temp.begin());
    return temp;
}

std::string ws2s(const std::wstring& s)
{
    std::string temp(s.length(),‘ ‘);
    std::copy(s.begin(), s.end(), temp.begin());
    return temp;
}

第一种方法:调用WideCharToMultiByte()和MultiByteToWideChar(),代码如下(关于详细的解释,可以参考《windows核心编程》):
 
#include<string>
#include<windows.h>
 
usingnamespace 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 = newchar[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>
usingnamespace 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>
usingnamespace std;
string ws2s(const wstring& ws)
{
         string curLocale = setlocale(LC_ALL, NULL);        // curLocale = "C";
 
         setlocale(LC_ALL, "chs");
 
         constwchar_t* _Source = ws.c_str();
         size_t _Dsize = 2 * ws.size() + 1;
         char *_Dest = newchar[_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");
 
         constchar* _Source = s.c_str();
         size_t _Dsize = s.size() + 1;
         wchar_t *_Dest = newwchar_t[_Dsize];
         wmemset(_Dest, 0, _Dsize);
         mbstowcs(_Dest,_Source,_Dsize);
         wstring result = _Dest;
         delete []_Dest;
 
         setlocale(LC_ALL, "C");
 
         return result;
}
 
//第四种方法,标准C++转换方法:(待续)
//第五种方法,在C++中使用C#类库:(待续
 其中第四种,我的实现始终存在一些问题。 第五种,我只是知道有这么一种方案,没有时间去详细了解,算是给一些提示吧。

 

std::string 与 std::wstring 转换方法的效率比较(转)

 

转自:http://blog.csdn.net/goof/article/details/7662652

// Calls the provided work function and returns the number of milliseconds   
// that it takes to call that function.  
template <class Function>  
__int64 time_call(Function&& f)  
{  
    __int64 begin = GetTickCount64();  
    f();  
    return GetTickCount64() - begin;  
}  
  
// Use WideCharToMultiByte and MultiByteToWideChar  
string WChar2Ansi(const wchar_t* pwszSrc)  
{  
    int nLen = WideCharToMultiByte(CP_ACP, 0, pwszSrc, -1, NULL, 0, NULL, NULL);  
       
    if (nLen<= 0) return string("");  
  
    char* pszDst = new char[nLen];  
    if (NULL == pszDst) return string("");  
  
    WideCharToMultiByte(CP_ACP, 0, pwszSrc, -1, pszDst, nLen, NULL, NULL);  
    pszDst[nLen -1] = 0;  
  
    string strTemp(pszDst);  
    delete [] pszDst;  
  
    return strTemp;  
}  
  
wstring Ansi2WChar(const char* pszSrc, int nLen)  
{  
    int nSize = MultiByteToWideChar(CP_ACP, 0, pszSrc, nLen, 0, 0);  
    if(nSize <= 0) return NULL;  
  
    wchar_t *pwszDst = new wchar_t[nSize+1];  
    if( NULL == pwszDst) return NULL;  
  
    MultiByteToWideChar(CP_ACP, 0, 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;  
}  
  
// Use wcstombs_s and mbstowcs_s   
string ws2s(wstring ws)  
{  
    const wchar_t* Source = ws.c_str();  
    size_t size = 2 * ws.size() + 1;  
    char* Dest = new char[size];  
    memset(Dest,0, size);  
    size_t len = 0;  
    wcstombs(Dest, Source, size);  
    //wcstombs_s(&len, Dest, size, Source, size);  
    string result = Dest;  
    delete [] Dest;  
  
    return result;  
}  
  
wstring s2ws(string s)  
{  
    const char* Source = s.c_str();  
    size_t size = s.size() + 1;  
    wchar_t* Dest = new wchar_t[size];  
    wmemset(Dest, 0, size);  
    size_t len = 0;  
    mbstowcs(Dest, Source, size);  
    //mbstowcs_s(&len, Dest, size, Source, size);  
    wstring result = Dest;  
    delete [] Dest;  
  
    return result;  
}  
  
// Testing   
    __int64 elapsed;  
    string input = "Hello, World.\\XXX\\XXX";  
    wstring winput = L"Hello, World.\\XXX\\XXX";  
    wchar_t dest[1000];  
  
    int count = 10000;  
    elapsed = time_call([input, &count]   
    {  
        while (count)  
        {  
            Ansi2WChar(input.c_str(), input.length());  
            count--;  
        }  
    });  
    memset(dest, 0, 1000);  
    _itow_s(elapsed, dest, 10);  
    OutputDebugStringW(L"Time:");  
    OutputDebugStringW(dest);  
    OutputDebugStringW(L"ms\n");  
  
    count = 10000;  
    elapsed = 0;  
    elapsed = time_call([input, &count]   
    {  
        while (count)  
        {  
            s2ws(input);  
            count--;  
        }  
    });  
    memset(dest, 0, 1000);  
    _itow_s(elapsed, dest, 10);  
    OutputDebugStringW(L"Time:");  
    OutputDebugStringW(dest);  
    OutputDebugStringW(L"ms\n");  
  
    count = 10000;  
    elapsed = 0;  
    elapsed = time_call([winput, &count]   
    {  
        while (count)  
        {  
            WChar2Ansi(winput.c_str());  
            count--;  
        }  
    });  
    memset(dest, 0, 1000);  
    _itow_s(elapsed, dest, 10);  
    OutputDebugStringW(L"Time:");  
    OutputDebugStringW(dest);  
    OutputDebugStringW(L"ms\n");  
  
    count = 10000;  
    elapsed = 0;  
    elapsed = time_call([winput, &count]   
    {  
        while (count)  
        {  
            ws2s(winput);  
            count--;  
        }  
    });  
    memset(dest, 0, 1000);  
    _itow_s(elapsed, dest, 10);  
    OutputDebugStringW(L"Time:");  
    OutputDebugStringW(dest);  
    OutputDebugStringW(L"ms\n");  
View Code

输出:

Time:78ms

Time:94ms

Time:62ms

Time:109ms

 

从输出结果可以看出

WideCharToMultiByte MultiByteToWideChar转换效率要比 mbstowcswcstombs高。

注意:如果使用mbstowcs则需要Disable Specific Warnings: 4996

 

示例代码:转自:http://codereview.stackexchange.com/questions/419/converting-between-stdwstring-and-stdstring

Here's a cross platform version I've written for a framework I'm working on, it uses the UTF8 code page but fell free to change as needed. This is a slimmed version as it doesn't contain all of the explicit macro definitions, but you can get the idea from it:

 1 #if defined(OMNI_OS_WIN)
 2     #include <windows.h>
 3 #endif
 4 #include <cctype>
 5 #include <cwctype>
 6 #include <string>
 7 // not sure if these are all needed .. haven't had my midnight coffee :)
 8 
 9 std::string omni::string::to_string(const std::wstring& str)
10 {
11     size_t sz = str.length();
12     #if defined(OMNI_OS_WIN)
13         int nd = WideCharToMultiByte(CP_UTF8, 0, &str[0], sz, NULL, 0, NULL, NULL);
14         std::string ret(nd, 0);
15         int w = WideCharToMultiByte(CP_UTF8, 0, &str[0], sz, &ret[0], nd, NULL, NULL);
16         if (w != sz) {
17             #if defined(OMNI_THROW_ON_ERR)
18                 throw omni::string_exception("Invalid size written");
19             #else
20                 OMNI_ERR_RETV("");
21             #endif
22         }
23         return ret;
24     #else
25         const wchar_t* p = str.c_str();
26         char* tp = new char[sz];
27         size_t w = wcstombs(tp, p, sz);
28         if (w != sz) {
29             delete[] tp;
30             #if defined(OMNI_THROW_ON_ERR)
31                 throw omni::string_exception("Invalid size written");
32             #else
33                 OMNI_ERR_RETV("");
34             #endif
35         }
36         std::string ret(tp);
37         delete[] tp;
38         return ret;
39     #endif
40 }
41 
42 std::wstring omni::string::to_wstring(const std::string& str)
43 {
44     #if defined(OMNI_OS_WIN)
45         size_t sz = str.length();
46         int nd = MultiByteToWideChar(CP_UTF8, 0, &str[0], sz, NULL, 0);
47         std::wstring ret(nd, 0);
48         int w = MultiByteToWideChar(CP_UTF8, 0, &str[0], sz, &ret[0], nd);
49         if (w != sz) {
50             #if defined(OMNI_THROW_ON_ERR)
51                 throw omni::string_exception("Invalid size written");
52             #else
53                 OMNI_ERR_RETV(L"");
54             #endif
55         }
56         return ret;
57     #else
58         const char* p = str.c_str();
59         size_t len = str.length();
60         size_t sz = len * sizeof(wchar_t);
61         wchar_t* tp = new wchar_t[sz];
62         size_t w = mbstowcs(tp, p, sz);
63         if (w != len) {
64             delete[] tp;
65             #if defined(OMNI_THROW_ON_ERR)
66                 throw omni::string_exception("Invalid size written");
67             #else
68                 OMNI_ERR_RETV(L"");
69             #endif
70         }
71         std::wstring ret(tp);
72         delete[] tp;
73         return ret;
74     #endif
75 }
View Code

Here's an example using it:

std::string s = "here's a standard string"; std::wstring w = L"here's a wide string"; std::string sw = omni::string::to_string(w); std::wstring ws = omni::string::to_wstring(s); std::cout << "s = " << s << std::endl; std::wcout << "w = " << w << std::endl; std::cout << "sw = " << sw << std::endl; std::wcout << "ws = " << ws << std::endl;

 

 

参考1:两种string的转换 http://blog.jqian.net/post/wstring.html

参考2:C++ Builder string相互转换 http://www.cnblogs.com/zhcncn/archive/2013/05/20/3089084.html

参考3:wstring与string相互转换  http://www.cnblogs.com/SunboyL/archive/2013/03/31/stringandwstring.html

参考4:http://codereview.stackexchange.com/questions/419/converting-between-stdwstring-and-stdstring

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM