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