17down voteaccepted

Here's some code. Only lightly tested and there's probably a few improvements. Call this function to convert a UTF-8 string to a UTF-16 wstring. If it thinks the input string is not UTF-8 then it will throw an exception, otherwise it returns the equivalent UTF-16 wstring.

std::wstring utf8_to_utf16(const std::string& utf8)
{
std::vector<unsigned long> unicode;
size_t i = 0;
while (i < utf8.size())
{
unsigned long uni;
size_t todo;
bool error = false;
unsigned char ch = utf8[i++];
if (ch <= 0x7F)
{
uni = ch;
todo = 0;
}
else if (ch <= 0xBF)
{
throw std::logic_error("not a UTF-8 string");
}
else if (ch <= 0xDF)
{
uni = ch&0x1F;
todo = 1;
}
else if (ch <= 0xEF)
{
uni = ch&0x0F;
todo = 2;
}
else if (ch <= 0xF7)
{
uni = ch&0x07;
todo = 3;
}
else
{
throw std::logic_error("not a UTF-8 string");
}
for (size_t j = 0; j < todo; ++j)
{
if (i == utf8.size())
throw std::logic_error("not a UTF-8 string");
unsigned char ch = utf8[i++];
if (ch < 0x80 || ch > 0xBF)
throw std::logic_error("not a UTF-8 string");
uni <<= 6;
uni += ch & 0x3F;
}
if (uni >= 0xD800 && uni <= 0xDFFF)
throw std::logic_error("not a UTF-8 string");
if (uni > 0x10FFFF)
throw std::logic_error("not a UTF-8 string");
unicode.push_back(uni);
}
std::wstring utf16;
for (size_t i = 0; i < unicode.size(); ++i)
{
unsigned long uni = unicode[i];
if (uni <= 0xFFFF)
{
utf16 += (wchar_t)uni;
}
else
{
uni -= 0x10000;
utf16 += (wchar_t)((uni >> 10) + 0xD800);
utf16 += (wchar_t)((uni & 0x3FF) + 0xDC00);
}
}
return utf16;
}

http://stackoverflow.com/questions/7153935/how-to-convert-utf-8-stdstring-to-utf-16-stdwstring

#pragma once
#include <string> #ifdef tstring
#error "\"tstring\" Macro has been defined."
#else
#ifdef _UNICODE
#define tstring wstring
#else
#define tstring string
#endif
#endif class EncodingConverter
{
public:
static int AnsiStrToWideStr(std::string& strSrc, std::wstring& strDest)
{
int nLen = strSrc.length() + ;
int nRet = ; nLen *= sizeof(wchar_t); wchar_t* pszW = new wchar_t[nLen];
memset(pszW, , nLen); nRet = MultiByteToWideChar(CP_ACP, , strSrc.c_str(), -, pszW, nLen); strDest = pszW;
delete[] pszW; return nRet;
}; static int WideStrToAnsiStr(std::wstring& strSrc, std::string& strDest)
{
int nLen = strSrc.length() + ;
int nRet = ; nLen *= sizeof(wchar_t); char* pszA = new char[nLen];
memset(pszA, , nLen); nRet = WideCharToMultiByte(CP_ACP, , strSrc.c_str(), -, pszA, nLen, NULL, NULL); strDest = pszA;
delete[] pszA; return nRet;
}; static int AnsiStrToTStr(std::string& strSrc, std::tstring& strDest)
{
int nRet = ; #ifdef _UNICODE
nRet = AnsiStrToWideStr(strSrc, strDest);
#else
strDest = strSrc;
nRet = strDest.length();
#endif return nRet;
}; static int TStrToAnsiStr(std::tstring& strSrc, std::string& strDest)
{
int nRet = ; #ifdef _UNICODE
nRet = WideStrToAnsiStr(strSrc, strDest);
#else
strDest = strSrc;
nRet = strDest.length();
#endif return nRet;
}; static int WideStrToTStr(std::wstring& strSrc, std::tstring& strDest)
{
int nRet = ; #ifdef _UNICODE
strDest = strSrc;
nRet = strDest.length();
#else
nRet = WideStrToAnsiStr(strSrc, strDest);
#endif return nRet;
}; static int TStrToWideStr(std::tstring& strSrc, std::wstring& strDest)
{
int nRet = ; #ifdef _UNICODE
strDest = strSrc;
nRet = strDest.length();
#else
nRet = AnsiStrToWideStr(strSrc, strDest);
#endif return nRet;
}; static std::string ToAnsiString(const wchar_t* lpStr)
{
std::wstring wide_string = lpStr;
std::string ansi_string; WideStrToAnsiStr(wide_string, ansi_string);
return ansi_string;
}; static std::string ToAnsiString(const char* lpStr)
{
return std::string(lpStr);
}; static std::wstring ToWideString(const wchar_t* lpStr)
{
return std::wstring(lpStr);
}; static std::wstring ToWideString(const char* lpStr)
{
std::string ansi_string = lpStr;
std::wstring wide_string; AnsiStrToWideStr(ansi_string, wide_string);
return wide_string;
}; static std::tstring ToTString(const char* lpStr)
{
#ifdef _UNICODE
return ToWideString(lpStr);
#else
return ToAnsiString(lpStr);
#endif
}; static std::tstring ToTString(const wchar_t* lpStr)
{
#ifdef _UNICODE
return ToWideString(lpStr);
#else
return ToAnsiString(lpStr);
#endif
}; static int WideStrToUtf8Str(std::wstring& strSrc, std::string& strDest)
{
int nRet = ;
int nLen = ; nLen = WideCharToMultiByte(CP_UTF8, , strSrc.c_str(), -, NULL, , NULL, NULL); char * lpUtf8Str = new char[nLen+];
memset(lpUtf8Str, , nLen);
nRet = WideCharToMultiByte(CP_UTF8, , strSrc.c_str(), -, lpUtf8Str, nLen, NULL, NULL);
strDest = lpUtf8Str;
delete[] lpUtf8Str; return nRet;
}; static int AnsiStrToUtf8Str(std::string& strSrc, std::string& strDest)
{
int nRet = ;
std::wstring wide_string; nRet = AnsiStrToWideStr(strSrc, wide_string);
nRet = WideStrToUtf8Str(wide_string, strDest); return nRet;
}; static int Utf8StrToWideStr(const std::string& strSrc, std::wstring& strDest)
{
int nRet = ;
int nLen = ; nLen = MultiByteToWideChar(CP_UTF8, , strSrc.c_str(), -, NULL, ); wchar_t* lpWideStr = new wchar_t[nLen];
memset(lpWideStr, , nLen*sizeof(lpWideStr[]));
nRet = MultiByteToWideChar(CP_UTF8, , strSrc.c_str(), -, lpWideStr, nLen);
strDest = lpWideStr;
delete[] lpWideStr; return nRet;
}; static int Utf8StrToAnsiStr(const std::string& strSrc, std::string& strDest)
{
int nRet = ;
std::wstring wide_string; nRet = Utf8StrToWideStr(strSrc, wide_string);
nRet = WideStrToAnsiStr(wide_string, strDest); return nRet;
}; static int Utf8StrToTStr(const std::string& strSrc, std::tstring& strDest)
{
#ifdef UNICODE
return Utf8StrToWideStr(strSrc, strDest);
#else
return Utf8StrToAnsiStr(strSrc, strDest);
#endif
}; static std::string ToUtf8String(const std::string& str)
{
std::string ansi_string = str;
std::string utf8_string; AnsiStrToUtf8Str(ansi_string, utf8_string);
return utf8_string;
}; static std::string ToUtf8String(const std::wstring& str)
{
std::wstring wide_string = str;
std::string utf8_string; WideStrToUtf8Str(wide_string, utf8_string);
return utf8_string;
};
};

https://github.com/yaocoder/utility/blob/master/src/common/EncodingConverter.h

utf8_to_utf16的更多相关文章

  1. boost::xml——基本操作以及中文乱码解决方案 (续)

    本博文主要想说明以下两点: 1.对于上一篇的<boost::xml——基本操作以及中文乱码解决方案>解释,这篇博文基本解决了正确输入输出中英文问题,但是好像还没有解决修改中文出现乱码的问题 ...

  2. C++ MFC std::string转为 std::wstring

    std::string转为 std::wstring std::wstring UTF8_To_UTF16(const std::string& source) { unsigned long ...

  3. 谷歌拼音自带lua

    function fast_string_banji(argument) return {"快捷1", "快捷2", "快捷3", &quo ...

  4. 谷歌拼音输入法扩展API开发指南

    为了帮助开发者在谷歌拼音输入法的基本输入功能基础上,开发和定义更丰富的扩展输入功能,谷歌拼音输入法提供了以Lua脚本编程语言为基础的输入法扩展API.利用输入法扩展API,开发者可以编写自定义的输入功 ...

随机推荐

  1. JAAS LOGIN IN WEBLOGIC SERVER--reference

    The Java Authentication and Authorization Service (JAAS) is a standard extension to the security in ...

  2. Linux学习笔记总结--CentOS 设置静态IP

    1.修改网卡配置 vi /etc/sysconfig/network-scripts/ifcfg-eth0 DEVICE=eth0 #描述网卡对应的设备别名,例如ifcfg-eth0的文件中它为eth ...

  3. iOS开发中常用的手势---边缘手势

    说明:以下方法是开发中使用的方法,有什么不对的或者好的方法,请多多指教! 此处的边缘手势是用来控制左侧抽屉视图的弹出以及收回. 添加手势 : 页面上有多个手势时需要遵循 UIGestureRecogn ...

  4. Effective C++ 笔记一 让自己习惯C++

    条款01:视C++为一个语言联邦 C++是个多重范型编程语言,一个同时支持面向过程形式.面向对象形式.函数形式.泛型形式.元编程形式的寓言. 将C++视为几个子语言: 传统C:区块.语句.预处理器.内 ...

  5. update inner join

    string sql = @"update a set a.M_ParentID=b.M_ParentID, a.M_Name=b.M_Name, a.M_Seq=b.M_Seq from ...

  6. .NET生成PDF文件

    C#未借助第三方组件,自己封装通用类,生成PDF文件. 调用方式: //路径 string path = @"C:\yuannwu22.pdf"; //内容 string strC ...

  7. (转)ie浏览器判断

    常用的 JavaScript 检测浏览器为 IE 是哪个版本的代码,包括是否是最人极端厌恶的 ie6 识别与检测. var isIE=!!window.ActiveXObject; var isIE6 ...

  8. CI 笔记 easyui 结合后,左侧导航跳转问题

    1. 在进行时,还没有做完整个项目时,可能不是最终稿 2. 从数据库中nav表中,读出url地址,然后,从admin中,重写这些url跳转 3. 在admin的控制器中,跳转写的并不完美, publi ...

  9. phpmyadmin备份小问题

    不要将imformation——shame或者mysql等备份,要有选择的备份表 关注我的新浪微博

  10. IO流基础加强

    字节流对象:InputStream,OutputStream 缓冲字节流对象:BufferedInputStream , BufferedOutputStream 用法和字符流对象一样,但也有区别, ...