#ifndef __CHAR_CONVERT_H__
#define __CHAR_CONVERT_H__
#ifdef OS_WINDOWS
#include <SDKDDKVer.h> //"targetver.h"
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN             //  从 Windows 头文件中排除极少使用的信息
#endif
// Windows 头文件:
#include <windows.h>
#else // Linux
#include "iconv.h"
#ifndef ICONV_BUFFER_SIZE
#define ICONV_BUFFER_SIZE 1024
#endif
#define WCHAR wchar_t
#ifdef _UNICODE
#define TCHAR wchar_t
#else
#define TCHAR char
#endif
#endif
/
#define E_CHAR      CWCharToChar::EChar
#define E_WCHAR     CWCharToChar::EWChar
#define E_UTF8      CWCharToChar::EUtf8
#define NULL_STR    CWCharToChar::GetNullStr()
static char g_NULL[2] = {0};
/
// 简单的wchar_t 和 char 转换类, 且包含与UTF8的转换
class CWCharToChar
{
public:
enum
{
EChar  = 1,
EWChar = 2,
EUtf8  = 4
};
private:
char    *   m_cDest;
wchar_t *   m_wcDest;
char    *   m_cUtf8;
unsigned int m_nSrcType;
public:
char    *   Char(void) { return m_cDest; }
wchar_t *   WChar(void){ return m_wcDest; }
bool        IsNullChar(void)  { return ( !m_cDest  || g_NULL == m_cDest ); }
bool        IsNullWChar(void) { return ( !m_wcDest || g_NULL == (char*)m_wcDest ); }
#if defined( _UTF8_ )
char    *   UTF8(void) { return m_cUtf8; }
bool        IsNullUTF8(void) { return ( !m_cUtf8   || g_NULL == m_cUtf8 ); }
#endif
TCHAR   *   TChar(void)
{
#ifdef _UNICODE
return WChar();
#else
return Char();
#endif
}
// ANSI/GBK 转 Unicode和UTF8的构造函数
CWCharToChar(const char* psrc, unsigned int nSrcType = EChar
#if defined( _UTF8_ )
, unsigned int nDestType = EUtf8)
#else
, unsigned int nDestType = EWChar)
#endif
: m_cDest(NULL)
, m_wcDest(NULL)
, m_cUtf8(NULL)
, m_nSrcType(nSrcType)
{
// 防止空指针
if( !psrc ) return;
if( !*psrc )  // 如果是空字符串,也返回空字符串
{
if( EChar == m_nSrcType ) m_cDest = (char*)psrc;
if( EUtf8 == m_nSrcType ) m_cUtf8 = (char*)psrc;
if( nDestType & EChar )  m_cDest  = g_NULL;
if( nDestType & EUtf8 )  m_cUtf8  = g_NULL;
if( nDestType & EWChar ) m_wcDest = (wchar_t*)g_NULL;
return;
}
#ifdef OS_WINDOWS
if( EChar == m_nSrcType )
{
m_cDest = (char*)psrc;
#if defined( _UTF8_ )
int nLen = MultiByteToWideChar (CP_ACP, 0, m_cDest, -1, NULL, 0);
m_wcDest = new wchar_t[nLen];
MultiByteToWideChar (CP_ACP, 0, m_cDest, -1, m_wcDest, nLen);
nLen = WideCharToMultiByte(CP_UTF8, 0, m_wcDest, -1, NULL, 0, NULL, NULL);
m_cUtf8 = new char[nLen + 1];
WideCharToMultiByte (CP_UTF8, 0, m_wcDest, -1, m_cUtf8, nLen, NULL,NULL);
#else
int nLen = MultiByteToWideChar (CP_ACP, 0, m_cDest, -1, NULL, 0);
m_wcDest = new wchar_t[nLen];
MultiByteToWideChar (CP_ACP, 0, m_cDest, -1, m_wcDest, nLen);
#endif
}
else if( EUtf8 == m_nSrcType )
{
m_cUtf8 = (char*)psrc;
int nLen = MultiByteToWideChar(CP_UTF8, 0, m_cUtf8, -1, NULL,0);
m_wcDest = new wchar_t[nLen+1];
MultiByteToWideChar(CP_UTF8, 0, m_cUtf8, -1, m_wcDest, nLen);
nLen = WideCharToMultiByte(CP_ACP, 0, m_wcDest, -1, NULL, 0, NULL, NULL);
m_cDest = new char[nLen + 1];
WideCharToMultiByte(CP_ACP, 0, m_wcDest, -1, m_cDest, nLen, NULL,NULL);
}
#else // Linux
if( EChar == m_nSrcType )
{
m_cDest = (char*)psrc;
if( nDestType & EUtf8 )
do_iconv_convert(psrc, &m_cUtf8, "GBK", "UTF-8");
if( nDestType & EWChar)
do_iconv_convert(psrc, (char**)&m_wcDest, "GBK", "wchar_t");
}
else if( EUtf8 == m_nSrcType )
{
m_cUtf8 = (char*)psrc;
if( nDestType & EChar)
do_iconv_convert(psrc, &m_cDest, "UTF-8", "GBK");
if( nDestType & EWChar)
do_iconv_convert(psrc, (char**)&m_wcDest, "UTF-8", "wchar_t");
}
#endif
}
// Unicode 转 ANSI/GBK和UTF8的构造函数
CWCharToChar(const wchar_t * psrc
#if defined( _UTF8_ )
, unsigned int nDestType = EUtf8)
#else
, unsigned int nDestType = EChar)
#endif
: m_cDest(NULL)
, m_wcDest(NULL)
, m_cUtf8(NULL)
, m_nSrcType(EWChar)
{
char * p = (char*)psrc;
if( !p ) return ;
m_wcDest = (wchar_t*)psrc;
if( 0 == *p && 0 == *(p+1) ) // 如果是空字符串,也返回空字符串
{
if( nDestType & EChar )  m_cDest  = g_NULL;
if( nDestType & EUtf8 )  m_cUtf8  = g_NULL;
return;
}
#ifdef OS_WINDOWS
// ANSI/GBK
{
int nLen = WideCharToMultiByte(CP_OEMCP,NULL, m_wcDest,-1,NULL,0,NULL,FALSE);
m_cDest = new char[nLen];
WideCharToMultiByte (CP_OEMCP,NULL,m_wcDest,-1, m_cDest, nLen,NULL,FALSE);
}
#if defined( _UTF8_ )
{
int nLen = WideCharToMultiByte(CP_UTF8, 0, m_wcDest, -1, NULL, 0, NULL, NULL);
m_cUtf8 = new char[nLen + 1];
WideCharToMultiByte (CP_UTF8, 0, m_wcDest, -1, m_cUtf8, nLen, NULL,NULL);
}
#endif
#else  // Linux
if( nDestType & EChar)
do_iconv_convert((char*)psrc, &m_cDest, "wchar_t", "GBK");
if( nDestType & EUtf8)
do_iconv_convert((char*)psrc, (char**)&m_cUtf8, "wchar_t", "UTF-8");
#endif
}
~CWCharToChar()
{
if( EChar == m_nSrcType )
{
if( m_wcDest && g_NULL != (char*)m_wcDest )   delete [] m_wcDest;
if( m_cUtf8  && g_NULL != m_cUtf8 )           delete [] m_cUtf8;
}
else if( EWChar == m_nSrcType )
{
if( m_cDest && g_NULL != m_cDest)             delete [] m_cDest;
if( m_cUtf8 && g_NULL != m_cUtf8)             delete [] m_cUtf8;
}
else if( EUtf8 == m_nSrcType )
{
if( m_cDest  && g_NULL != m_cDest)            delete [] m_cDest;
if( m_wcDest && g_NULL != (char*)m_wcDest )   delete [] m_wcDest;
}
}
// Using iconv  for Linux
#ifndef OS_WINDOWS
int  do_iconv_convert(const char* pSrc, char**ppOut, const char* pszFromCode, const char* pszToCode)
{
iconv_t cd = iconv_open(pszToCode, pszFromCode);
if(cd == (iconv_t)(-1))
{
printf("iconv_open failed, errno: %d - %s\n", errno, strerror(errno));
*ppOut = g_NULL;  // 为了防止给std::string赋值抛异常而导致程序终止
return -1;
}
iconv(cd, NULL, NULL, NULL, NULL);
size_t nSLen = 0, nOLen = 0;
if( m_nSrcType == EWChar )
#ifdef OS_WINDOWS
nSLen = wcslen((wchar_t*)pSrc) * 2;  // 乘以2,转换成char的长度
#else  // Linux
nSLen = wcslen((wchar_t*)pSrc) * 4;  // for Unicode -> GBK/UTF8, Linux 乘以4
#endif
else
nSLen = strlen(pSrc);
if( 0 == strcmp( pszToCode, "wchar_t"))
nOLen = nSLen * 4;        // for GBK -> Unicode
else
nOLen = nSLen * 2;
size_t nORawLen = nOLen;
char* pOut = new char[nOLen+4];
char* pOutStart = pOut;
char ** ppin = (char**)&pSrc;
char ** ppout = &pOut;
#ifdef _DEBUG
printf("Convert: %s[%lu] -> %s[%lu] bytes\n", pszFromCode, nSLen, pszToCode, nOLen);
#endif
size_t ret = iconv(cd, (char**)ppin, &nSLen, (char**)ppout, &nOLen);
if( 0 == ret )  // 转换完成成功
{
iconv_close(cd);
int nOutLen = nORawLen - nOLen;
*(pOutStart + nOutLen) = 0;
*(pOutStart + nOutLen + 1) = 0; // 给转换Unicode之用
*ppOut = pOutStart;
return nOutLen;
}
else  // 全部或部分错误
{
printf("iconv failed, errno: %d - %s\n", errno, strerror(errno));
iconv_close(cd);
delete [] pOutStart;
*ppOut = g_NULL;  // 为了防止给std::string赋值抛异常而导致程序终止
return -1;
}
}
#endif
static const char* GetNullStr(void){ return g_NULL; }
};
#endif //__CHAR_CONVERT_H__

iconv 转换字符编码,兼容VC转换相关推荐

  1. iconv 判断字符编码_iconv 字符集转换报错

    iconv 字符集转换出错 本帖最后由 zw91683 于 2014-02-26 15:59:48 编辑 最近有个项目在用字符集转换,网上查了下iconv的用法,直接拿过来用,发现运行一直出错,代码如 ...

  2. Java工具类-转换字符编码

    package common; /***字符串处理公用类 */ public class DealString {/*** 转换字符编码 由"iso-8859-1"西文转换为简体中 ...

  3. (转载)Python常见字符编码间的转换

    Python常见字符编码间的转换 主要内容:     1.Unicode 和 UTF-8的爱恨纠葛     2.字符在硬盘上的存储     3.编码的转换     4.验证编码是否转换正确     5 ...

  4. python转换字符编码_转:Python常见字符编码及其之间的转换

    一.Python常见字符编码 字符编码的常用种类介绍 第一种:ASCII码 ASCII(American Standard Code for Information Interchange,美国信息交 ...

  5. python转换字符编码_Python常见字符编码间的转换

    学习Python,字符编码间的转换是绕不过去的一只拦路虎,不把编码彻底搞明白,总有一天它会猝不及防坑你一把. Python2.x和Python3.x在字符编码的设置上也有很大区别(Python3未来将 ...

  6. iconv 判断字符编码_iconv字符编码转换全攻略

    iconv(http://www.gnu.org/software/libiconv/)是一个开源的字符编码转换库,可以"方便"的完成几乎所有的编码转换工作.说简单是因为,它常用的 ...

  7. qt字符编码及数据格式转换

    1.字符编码 QString: QString内部可能是使用unicode字符集来存储文字,UTF-8以字节为单位对Unicode进行编码.QString里面的汉字是UTF-8编码的字符集,QStri ...

  8. Python常见字符编码间的转换教程

    1. 前言 Python2.x和Python3.x在字符编码的设置上也有很大区别(Python3未来将是主流,所以Python3为主),今天我们就来一起学习下. 2. Unicode 和 UTF-8的 ...

  9. iconv 判断字符编码_GBK 和 UTF8编码

    相关学习内容: https://study.163.com/course/courseMain.htm?courseId=1210747815&share=2&shareId=4800 ...

最新文章

  1. python3-泊松分布
  2. Java awt Desktop 无法调用系统浏览器
  3. 四层负载均衡——LVS
  4. luogu P4725 多项式对数函数 (模板题、FFT、多项式求逆、求导和积分)
  5. linux下MySQL与jdk安装
  6. ObjectAnimator属性动画应用demo
  7. 不要怂,就是GAN (生成式对抗网络) (五):无约束条件的 GAN 代码与网络的 Graph...
  8. 如何使用移动硬盘加密
  9. Selenium Chrome浏览器的启动以及proxy设置
  10. Angular实践----前言与概览
  11. 微软家庭服务器,微软下一代Windows家庭服务器Vail初印象
  12. C语言实现飞机售票系统
  13. 服务器系统 与win7系统,服务器系统win7
  14. Golang程序调试 -- 内存泄漏pprof工具
  15. 火狐浏览器怎么清理缓存、cookie等?
  16. Liunx系统格式化磁盘和挂载备份盘
  17. java 基本类型 不赋值_探究Java中基本类型和部分包装类在声明变量时不赋值的情况下java给他们的默认赋值...
  18. 服务器配置mysql
  19. C语言编码图书借阅系统
  20. 开发者论坛一周精粹(第三十期) 晒技术关键词逢8有喜 云大使ACP享杭州云栖门票等特权...

热门文章

  1. Win11安装 (Win11 22H2) 不联网 跳过联网 激活 终极教程(解决:无法跳过联网,糟糕你已断开internet连接等问题)
  2. 算法初探系列3 -深度优先搜索之剪枝策略
  3. OR和AR系统的区别
  4. Office 好压 看图王 搜狗
  5. 3.6版本后的matplotlib使用plot_surface作图无效果的解决方法
  6. 读论文-Control of Memory, Active Perception, and Action in Minecraft
  7. 商品陈列原则及陈列形式
  8. 流媒体服务器文件传输,mStream - 从任何地方流式传输音乐的个人流媒体服务器...
  9. SQL Server 2005 中的商务智能和数据仓库
  10. ruby 程序员修炼之道_面向系统管理员的Ruby