宽字符和窄字符之间的转换,以及对中文的处理问题总汇
直接代码:
注:编译环境VS2010 SP1
1 /*实现宽字节和窄字符转换以及中文文件的输入输出*/ 2 3 #include <iostream> 4 #include <string> 5 #include <fstream> 6 #include <locale> 7 #include <codecvt> 8 #include <windows.h> 9 #include <tchar.h> 10 using namespace std; 11 12 //----------------------------------------------------------------------------- 13 //转换宽窄字符串时可以成功,并且支持中文转换 14 const std::wstring s2ws(const std::string& s) 15 { 16 std::locale old_loc = std::locale::global(std::locale("")); 17 const char* src_str = s.c_str(); 18 const size_t buffer_size = s.size() + 1; 19 wchar_t* dst_wstr = new wchar_t[buffer_size]; 20 wmemset(dst_wstr, 0, buffer_size); 21 mbstowcs(dst_wstr, src_str, buffer_size); 22 std::wstring result = dst_wstr; 23 delete []dst_wstr; 24 std::locale::global(old_loc); 25 return result; 26 } 27 const std::string ws2s(const std::wstring& ws) 28 { 29 std::locale old_loc = std::locale::global(std::locale("")); 30 const wchar_t* src_wstr = ws.c_str(); 31 size_t buffer_size = ws.size() * 4 + 1; 32 char* dst_str = new char[buffer_size]; 33 memset(dst_str, 0, buffer_size); 34 wcstombs(dst_str ,src_wstr, buffer_size); 35 std::string result = dst_str; 36 delete []dst_str; 37 std::locale::global(old_loc); 38 return result; 39 } 40 41 //----------------------------------------------------------------------------- 42 //转换宽窄字符串时可以成功,并且支持中文转换 43 std::string WChar2Ansi(LPCWSTR pwszSrc) 44 { 45 int nLen = WideCharToMultiByte(CP_ACP, 0, pwszSrc, -1, NULL, 0, NULL, NULL); 46 47 if (nLen<= 0) return std::string(""); 48 49 char* pszDst = new char[nLen]; 50 if (NULL == pszDst) return std::string(""); 51 ZeroMemory(pszDst, nLen); 52 53 WideCharToMultiByte(CP_ACP, 0, pwszSrc, -1, pszDst, nLen, NULL, NULL); 54 pszDst[nLen -1] = 0; 55 56 std::string strTemp(pszDst); 57 delete [] pszDst; 58 59 return strTemp; 60 } 61 std::wstring Ansi2WChar(LPCSTR pszSrc, int nLen) 62 63 { 64 int nSize = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pszSrc, nLen, 0, 0); 65 if(nSize <= 0) return NULL; 66 67 WCHAR *pwszDst = new WCHAR[nSize+1]; 68 if( NULL == pwszDst) return NULL; 69 ZeroMemory(pwszDst, nSize); 70 71 MultiByteToWideChar(CP_ACP, 0, pszSrc, nLen, pwszDst, nSize); 72 pwszDst[nSize] = 0; 73 74 if( pwszDst[0] == 0xFEFF) // skip Oxfeff 75 for(int i = 0; i < nSize; i ++) 76 pwszDst[i] = pwszDst[i+1]; 77 78 wstring wcharString(pwszDst); 79 delete pwszDst; 80 81 return wcharString; 82 } 83 84 //----------------------------------------------------------------------------- 85 //虽然可以转换宽窄字符串,但是不能解决中文乱码问题 86 std::wstring strtowstr(const std::string &i_str) 87 { 88 std::wstring_convert<std::codecvt_utf8<wchar_t>> conv; 89 std::wstring l_wstr = conv.from_bytes(i_str); 90 return l_wstr; 91 } 92 std::string wstrtostr(const std::wstring &i_wstr) 93 { 94 std::wstring_convert<std::codecvt_utf8<wchar_t>> conv; 95 std::string l_str = conv.to_bytes(i_wstr); 96 return l_str; 97 } 98 99 //----------------------------------------------------------------------------- 100 bool OutputFile(const string &i_strFileName, const string &i_strExt) 101 { 102 std::locale old_loc = std::locale::global(std::locale("")); 103 ofstream ofs(i_strFileName, ifstream::out|ifstream::binary); 104 if (ofs.rdstate()!=ios_base::goodbit) 105 { 106 cout << "open file error." << endl; 107 return false; 108 } 109 ofs.write(i_strExt.c_str(), i_strExt.length()); 110 ofs.clear(); 111 ofs.close(); 112 std::locale::global(old_loc); 113 return true; 114 } 115 bool OutputFileW(const string &i_strFileName, const wstring &i_wstrExt) 116 { 117 std::locale old_loc = std::locale::global(std::locale("")); 118 wofstream wofs(i_strFileName, ifstream::out|ifstream::binary); 119 if (wofs.rdstate()!=ios_base::goodbit) 120 { 121 wcout << L"open file error." << endl; 122 return false; 123 } 124 wofs.write(i_wstrExt.c_str(), i_wstrExt.length()); 125 wofs.clear(); 126 wofs.close(); 127 std::locale::global(old_loc); 128 return true; 129 } 130 //bool OutputFile2(const string &i_strFileName, const string &i_strExt) 131 //{ 132 // //1 133 // //std::locale loc(""); 134 // //typedef codecvt<wchar_t, char, std::mbstate_t> facet_type; 135 // //const std::locale::facet &myfacet = use_facet<facet_type>(loc); 136 // //std::locale curloc(loc, &myfacet); 137 // 138 // //std::locale loc(""); 139 // //std::codecvt_utf8_utf16<wchar_t> *pconv = new std::codecvt_utf8_utf16<wchar_t> (); 140 // //std::locale curloc(loc, pconv); 141 // 142 // ofstream ofs(i_strFileName, ifstream::out|ifstream::binary); 143 // if (ofs.rdstate()!=ios_base::goodbit) 144 // { 145 // cout << "open file error." << endl; 146 // return false; 147 // } 148 // ofs.imbue(std::locale(std::locale(""), new std::codecvt_utf8_utf16<wchar_t>)); 149 // //ofs.imbue(curloc); 150 // ofs.write(i_strExt.c_str(), i_strExt.length()); 151 // ofs.clear(); 152 // ofs.close(); 153 // 154 // return true; 155 //} 156 157 //测试以上代码部分 158 void main() 159 { 160 string strExt = "这是一个窄字符串"; 161 wstring wstrExt = L"这是一个宽字符串"; 162 163 //string strRet; 164 //wstring wstrRet; 165 //wstrRet = s2ws(strExt); 166 //strRet = ws2s(wstrExt); 167 //cout << strRet << endl; 168 //wcout << wstrRet << endl; 169 170 //string strFileName1 = "F:\\Desktop\\20140411\\测试\\output.txt"; 171 //bool f1 = OutputFile(strFileName1, strExt); 172 //string strFileName2 = "F:\\Desktop\\20140411\\测试\\outputw.txt"; 173 //bool f2 = OutputFileW(strFileName2, wstrExt); 174 175 //LPCWSTR pwstr = _TEXT("windows宽字符串"); 176 //std::string strResult = WChar2Ansi(pwstr); 177 //cout << strResult << endl; 178 //LPCSTR pstr = "windows窄字符串"; 179 ////size_t cnlen = lstrlenA(pstr); 180 //size_t cblen = lstrlenA(pstr)*sizeof(CHAR); 181 //std::wstring wstrResult = Ansi2WChar(pstr, cblen); 182 //wcout << wstrResult << endl; 183 184 //std::wstring wstr = L"wchar_t宽字符"; 185 //std::string strResult = wstrtostr(wstr); 186 //cout << "宽字符转窄字符:" << strResult << endl; 187 188 cout << endl; 189 }
煮酒论英雄