GBK和UTF8之间的转换 C语言

2024-05-24 04:18
文章标签 语言 转换 之间 gbk utf8

本文主要是介绍GBK和UTF8之间的转换 C语言,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

GBK和UTF8之间的转换可以使用MultiByteToWideChar和WideCharToMultiByte两个API,方法是先把它们转换为中间编码Unicode,再转换为对应的编码即可。



#include  < stdio.h >
#include 
< windows.h >

// GBK编码转换到UTF8编码
int  GBKToUTF8(unsigned  char   *  lpGBKStr,unsigned  char   *  lpUTF8Str, int  nUTF8StrLen)
{
    wchar_t 
*  lpUnicodeStr  =  NULL;
    
int  nRetLen  =   0 ;

    
if ( ! lpGBKStr)   // 如果GBK字符串为NULL则出错退出
         return   0 ;

    nRetLen 
=  ::MultiByteToWideChar(CP_ACP, 0 ,( char   * )lpGBKStr, - 1 ,NULL,NULL);   // 获取转换到Unicode编码后所需要的字符空间长度
    lpUnicodeStr  =   new  WCHAR[nRetLen  +   1 ];   // 为Unicode字符串空间
    nRetLen  =  ::MultiByteToWideChar(CP_ACP, 0 ,( char   * )lpGBKStr, - 1 ,lpUnicodeStr,nRetLen);   // 转换到Unicode编码
     if ( ! nRetLen)   // 转换失败则出错退出
         return   0 ;

    nRetLen 
=  ::WideCharToMultiByte(CP_UTF8, 0 ,lpUnicodeStr, - 1 ,NULL, 0 ,NULL,NULL);   // 获取转换到UTF8编码后所需要的字符空间长度
    
    
if ( ! lpUTF8Str)   // 输出缓冲区为空则返回转换后需要的空间大小
    {
        
if (lpUnicodeStr)
            delete []lpUnicodeStr;
        
return  nRetLen;
    }
    
    
if (nUTF8StrLen  <  nRetLen)   // 如果输出缓冲区长度不够则退出
    {
        
if (lpUnicodeStr)
            delete []lpUnicodeStr;
        
return   0 ;
    }

    nRetLen 
=  ::WideCharToMultiByte(CP_UTF8, 0 ,lpUnicodeStr, - 1 ,( char   * )lpUTF8Str,nUTF8StrLen,NULL,NULL);   // 转换到UTF8编码
    
    
if (lpUnicodeStr)
        delete []lpUnicodeStr;
    
    
return  nRetLen;
}

//  UTF8编码转换到GBK编码
int  UTF8ToGBK(unsigned  char   *  lpUTF8Str,unsigned  char   *  lpGBKStr, int  nGBKStrLen)
{
    wchar_t * lpUnicodeStr 
=  NULL;
    
int  nRetLen  =   0 ;

    
if ( ! lpUTF8Str)   // 如果UTF8字符串为NULL则出错退出
         return   0 ;

    nRetLen 
=  ::MultiByteToWideChar(CP_UTF8, 0 ,( char   * )lpUTF8Str, - 1 ,NULL,NULL);   // 获取转换到Unicode编码后所需要的字符空间长度
    lpUnicodeStr  =   new  WCHAR[nRetLen  +   1 ];   // 为Unicode字符串空间
    nRetLen  =  ::MultiByteToWideChar(CP_UTF8, 0 ,( char   * )lpUTF8Str, - 1 ,lpUnicodeStr,nRetLen);   // 转换到Unicode编码
     if ( ! nRetLen)   // 转换失败则出错退出
         return   0 ;

    nRetLen 
=  ::WideCharToMultiByte(CP_ACP, 0 ,lpUnicodeStr, - 1 ,NULL,NULL,NULL,NULL);   // 获取转换到GBK编码后所需要的字符空间长度
    
    
if ( ! lpGBKStr)   // 输出缓冲区为空则返回转换后需要的空间大小
    {
        
if (lpUnicodeStr)
            delete []lpUnicodeStr;
        
return  nRetLen;
    }
    
    
if (nGBKStrLen  <  nRetLen)   // 如果输出缓冲区长度不够则退出
    {
        
if (lpUnicodeStr)
            delete []lpUnicodeStr;
        
return   0 ;
    }

    nRetLen 
=  ::WideCharToMultiByte(CP_ACP, 0 ,lpUnicodeStr, - 1 ,( char   * )lpGBKStr,nRetLen,NULL,NULL);   // 转换到GBK编码
    
    
if (lpUnicodeStr)
        delete []lpUnicodeStr;
    
    
return  nRetLen;
}

// 使用这两个函数的例子
int  main()
{
    
char  cGBKStr[]  =   " 我是中国人! " ;
    
char   *  lpGBKStr  =  NULL;
    
char   *  lpUTF8Str  =  NULL;
    FILE 
*  fp  =  NULL;
    
int  nRetLen  =   0 ;

    nRetLen 
=  GBKToUTF8((unsigned  char   * )cGBKStr,NULL,NULL);
    printf(
" 转换后的字符串需要的空间长度为:%d  " ,nRetLen);
    lpUTF8Str 
=   new   char [nRetLen  +   1 ];
    nRetLen 
=  GBKToUTF8((unsigned  char   * )cGBKStr,(unsigned  char   * )lpUTF8Str,nRetLen);
    
if (nRetLen)
    {
        printf(
" GBKToUTF8转换成功! " );
    }
    
else
    {
        printf(
" GBKToUTF8转换失败! " );
        
goto  Ret0;
    }
    
    fp 
=  fopen( " C:\GBK转UTF8.txt " , " wb " );   // 保存到文本文件
    fwrite(lpUTF8Str,nRetLen, 1 ,fp);
    fclose(fp);
    
    getchar();  
// 先去打开那个文本文件看看,单击记事本的“文件”-“另存为”菜单,在对话框中看到编码框变为了“UTF-8”说明转换成功了

    nRetLen 
=  UTF8ToGBK((unsigned  char   * )lpUTF8Str,NULL,NULL);   // 再转回来
    printf( " 转换后的字符串需要的空间长度为:%d  " ,nRetLen);
    lpGBKStr 
=   new   char [nRetLen  +   1 ];
    nRetLen 
=  UTF8ToGBK((unsigned  char   * )lpUTF8Str,(unsigned  char   * )lpGBKStr,nRetLen);
    
if (nRetLen)
    {
        printf(
" UTF8ToGBK转换成功!  " );
    }
    
else
    {
        printf(
" UTF8ToGBK转换失败!  " );
        
goto  Ret0;
    }

    fp 
=  fopen( " C:\UTF8转GBK.txt " , " wb " );   // 保存到文本文件
    fwrite(lpGBKStr,nRetLen, 1 ,fp);
    fclose(fp);
    
    getchar();  
// 再去打开文本文件看看,发现编码框又变为了“ANSI”说明转换成功了

Ret0:
    
if (lpGBKStr)
        delete []lpGBKStr;
    
    
if (lpUTF8Str)
        delete []lpUTF8Str;
        
    
return   0 ;
}

 在网上看到的一些文章说,UTF8转换为GBK的时候会有问题,特别是当UTF8字符串中的汉字数为奇数时。关于这个问题我没有去验证过,而且我对UTF8和GB2312的编码还不是很熟悉,呵呵,等以后有空的时候再去了解一下编码吧。

这篇关于GBK和UTF8之间的转换 C语言的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/997343

相关文章

解决IDEA报错:编码GBK的不可映射字符问题

《解决IDEA报错:编码GBK的不可映射字符问题》:本文主要介绍解决IDEA报错:编码GBK的不可映射字符问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录IDEA报错:编码GBK的不可映射字符终端软件问题描述原因分析解决方案方法1:将命令改为方法2:右下jav

Java controller接口出入参时间序列化转换操作方法(两种)

《Javacontroller接口出入参时间序列化转换操作方法(两种)》:本文主要介绍Javacontroller接口出入参时间序列化转换操作方法,本文给大家列举两种简单方法,感兴趣的朋友一起看... 目录方式一、使用注解方式二、统一配置场景:在controller编写的接口,在前后端交互过程中一般都会涉及

Java对象转换的实现方式汇总

《Java对象转换的实现方式汇总》:本文主要介绍Java对象转换的多种实现方式,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录Java对象转换的多种实现方式1. 手动映射(Manual Mapping)2. Builder模式3. 工具类辅助映

C语言中位操作的实际应用举例

《C语言中位操作的实际应用举例》:本文主要介绍C语言中位操作的实际应用,总结了位操作的使用场景,并指出了需要注意的问题,如可读性、平台依赖性和溢出风险,文中通过代码介绍的非常详细,需要的朋友可以参... 目录1. 嵌入式系统与硬件寄存器操作2. 网络协议解析3. 图像处理与颜色编码4. 高效处理布尔标志集合

Go语言开发实现查询IP信息的MCP服务器

《Go语言开发实现查询IP信息的MCP服务器》随着MCP的快速普及和广泛应用,MCP服务器也层出不穷,本文将详细介绍如何在Go语言中使用go-mcp库来开发一个查询IP信息的MCP... 目录前言mcp-ip-geo 服务器目录结构说明查询 IP 信息功能实现工具实现工具管理查询单个 IP 信息工具的实现服

python实现svg图片转换为png和gif

《python实现svg图片转换为png和gif》这篇文章主要为大家详细介绍了python如何实现将svg图片格式转换为png和gif,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录python实现svg图片转换为png和gifpython实现图片格式之间的相互转换延展:基于Py

C 语言中enum枚举的定义和使用小结

《C语言中enum枚举的定义和使用小结》在C语言里,enum(枚举)是一种用户自定义的数据类型,它能够让你创建一组具名的整数常量,下面我会从定义、使用、特性等方面详细介绍enum,感兴趣的朋友一起看... 目录1、引言2、基本定义3、定义枚举变量4、自定义枚举常量的值5、枚举与switch语句结合使用6、枚

C#实现将Excel表格转换为图片(JPG/ PNG)

《C#实现将Excel表格转换为图片(JPG/PNG)》Excel表格可能会因为不同设备或字体缺失等问题,导致格式错乱或数据显示异常,转换为图片后,能确保数据的排版等保持一致,下面我们看看如何使用C... 目录通过C# 转换Excel工作表到图片通过C# 转换指定单元格区域到图片知识扩展C# 将 Excel

C++使用printf语句实现进制转换的示例代码

《C++使用printf语句实现进制转换的示例代码》在C语言中,printf函数可以直接实现部分进制转换功能,通过格式说明符(formatspecifier)快速输出不同进制的数值,下面给大家分享C+... 目录一、printf 原生支持的进制转换1. 十进制、八进制、十六进制转换2. 显示进制前缀3. 指

使用Python开发一个带EPUB转换功能的Markdown编辑器

《使用Python开发一个带EPUB转换功能的Markdown编辑器》Markdown因其简单易用和强大的格式支持,成为了写作者、开发者及内容创作者的首选格式,本文将通过Python开发一个Markd... 目录应用概览代码结构与核心组件1. 初始化与布局 (__init__)2. 工具栏 (setup_t