问题描述:


如果你有把曾经的php或者java的老代码用go重写的经验,很可能会遇到gb2312转utf-8的问题

最近有同学在工作有使用到iconv-go这个库,涉及到转换字符的,出现如下报错,然后再咨询我,然后我自己也学习了一下。

报错信息如下:

invalid or incomplete multibyte or wide character

用到的golang转化库为:

github.com/djimenez/iconv-go

使用的函数为:

body, err = iconv.ConvertString(body, "GBK", "utf-8")

解决思路:

进去github.com/djimenez/iconv-go点击源码查看

首先iconv.ConvertString的实现是在iconv.go中

func ConvertString(input string, fromEncoding string, toEncoding string) (output string, err error) {  // create a temporary converter  converter, err := NewConverter(fromEncoding, toEncoding)  if err == nil {    // convert the string    output, err = converter.ConvertString(input)    // close the converter    converter.Close()  }  return}

通过以上发现, 它调用了

NewConverter(fromEncoding, toEncoding)

新建了一个结构体Converter,调用下面结构体的实现的

output, err = converter.ConvertString(input)

继续跟踪这个结构方法,在converter.go内找到实现

type Converter struct {  context C.iconv_t  open    bool}// Initialize a new Converter. If fromEncoding or toEncoding are not supported by// iconv then an EINVAL error will be returned. An ENOMEM error maybe returned if// there is not enough memory to initialize an iconv descriptorfunc NewConverter(fromEncoding string, toEncoding string) (converter *Converter, err error) {  converter = new(Converter)  // convert to C strings  toEncodingC := C.CString(toEncoding)  fromEncodingC := C.CString(fromEncoding)  // open an iconv descriptor  converter.context, err = C.iconv_open(toEncodingC, fromEncodingC)  // free the C Strings  C.free(unsafe.Pointer(toEncodingC))  C.free(unsafe.Pointer(fromEncodingC))  // check err  if err == nil {    // no error, mark the context as open    converter.open = true  }  return}

可以看出,它底层调用的是CGO库转化实现

converter.context, err = C.iconv_open(toEncodingC, fromEncodingC)

通过查询C库的文档man iconv_open,DESCRIPTION部分有如下介绍

The empty encoding name "" is equivalent to "char": it denotes the locale dependent character encoding.When the string "//TRANSLIT" is appended to tocode, transliteration is activated. This means that when a character cannot  be  represented  in  the  targetcharacter set, it can be approximated through one or several similarly looking characters.When the string "//IGNORE" is appended to tocode, characters that cannot be represented in the target character set will be silently discarded.The resulting conversion descriptor can be used with iconv any number of times. It remains valid until deallocated using iconv_close.A  conversion descriptor contains a conversion state. After creation using iconv_open, the state is in the initial state. Using iconv modifies the descrip-tor's conversion state. (This implies that a conversion descriptor can not be used in multiple threads simultaneously.) To bring the state back to the ini-tial state, use iconv with NULL as inbuf argument.

重点是这句话

When the string "//IGNORE" is appended to tocode, characters that cannot be represented in the target character set will be silently discarded.

大致意思是说,在"tocode"之后加"//IGNORE",那些不能被tocode显示的字符将会自动被忽略,oh good,正好是我想要的.

由这些层层调用关系

ConvertString(input string, fromEncoding string, toEncoding string)NewConverter(fromEncoding string, toEncoding string) (converter *Converter, err error)C.iconv_open(toEncodingC, fromEncodingC)

我们只需将//IGNORE传递到c库既可支持

所以代码改为:

body, err = iconv.ConvertString(body, "GBK", "utf-8//IGNORE")

经测试,没有报err,大功告成.


重述一下解决方案:

body, err = iconv.ConvertString(body, "GBK", "utf-8//IGNORE")

推荐阅读

  • Java 微服务能像 Go 一样快吗?

福利我为大家整理了一份从入门到进阶的Go学习资料礼包,包含学习建议:入门看什么,进阶看什么。关注公众号 「polarisxu」,回复 ebook获取;还可以回复「进群」,和数万 Gopher 交流学习。

转结构体_golang处理gb2312转utf8编码的问题相关推荐

  1. vbs 转码 gb2312转换为UTF-8编码的函数

    <% 1.'UTF转GB---将UTF8编码文字转换为GB编码文字 function UTF2GB(UTFStr) for Dig=1 to len(UTFStr)   '如果UTF8编码文字以 ...

  2. JavaScript和C#通用gb2312和utf8编码解码函数简单实现

    1.javascript实现gb2312编码解码 随便看到一段话如下: "老赵的jscex https://github.com/JeffreyZhao/jscex/blob/master/ ...

  3. Gb2312及Gb2312转Utf-8编码的UrlEncode编码解码(全)

    为了一个gb2312下post中文参数到utf-8页面的程序,随闷的难受,查了一下午资料,大部分是讲Gb2312传到Gb2312页面的UrlEncode,没有提供到Utf-8页面的UrlEncode, ...

  4. C++ 中ANSI/ASII/GB2312/Unicode/Utf-8编码的区别

    ANSI:基于ASII的语言扩展编码,在简体中文Windows操作系统中,ANSI 编码代表 GBK 编码:在英文Windows操作系统中,ANSI 编码代表 ASCII编码:在繁体中文Windows ...

  5. Javascript 实现gb2312和utf8编码的互换

    今天才找到的,只有gb2312转成utf8的函数,后来自己按照作者思路又加写了一个utf8转gb2312 的函数 先写这,以免忘了 <script language="javascri ...

  6. 判断一段文件是UTF-8编码还是GB2312的编码方式

    分类: 算法 cpp2012-03-10 16:01 7120人阅读 评论(2) 收藏 举报 null生活c 对于只包含中文和英文的文本中判断编码方式是非常简单的,中文的编码方式最常用的是GBK,字符 ...

  7. FFMpeg4.0相关结构体和函数

    文章目录 相关指令 相关结构体 av_register_all() 已废弃无需添加 avformat_network_init() 初始化网络封装库 AVFormatContext结构体 AVDict ...

  8. GB2312和UTF-8区别与用法

    GB2312和UTF-8区别与用法 gb2312和utf-8就都是一种字符编码.在之前的文章[gbk和gb2312的区别有哪些?]中,已经为大家总结了gbk与gb2312的区别,并且也具体介绍了什么是 ...

  9. GBK编码和UTF-8编码的区别

    GBK编码是中文编码,中文.英文均采用双字节编码(1字节=8位),它支持简体中文和繁体中文. gb-2312仅支持简体中文编码,GBK编码向下兼容gb-2312. UTF-8编码是多字符集编码,支持多 ...

最新文章

  1. 框架和库有什么区别? [关闭]
  2. 我学员的一个问题及其我对之的解答,关于lr返回值问题
  3. Lecture 2 Introduction
  4. Harfbuzz API 基本用法
  5. Fix Elementary Boot Screen (plymouth) After Installing Nvidia Drivers
  6. 蓝桥杯2019年第十届C/C++省赛B组第八题-等差数列
  7. C#反编译工具Reflector.exe教程
  8. datagrid编辑单元格中的内容
  9. 阿佐数据分析python小抄【pandas基础数据处理】
  10. android加载本地图片
  11. 实现收藏本站和设为首页功能
  12. VC++ 利用MFC的CWindowDC类实现画线功能 在桌面窗口中画线 绘制彩色线条 CPen nPenStyle nWidth crColor
  13. C语言基础知识入门和C语言入门基础知识大全
  14. MySQL 查看SQL语句执行阶段和进度信息
  15. 群狼调研开展电器店神秘顾客暗访违规稽核项目
  16. VUE不兼容显卡问题
  17. net start mysql启动mysql时报错:发生系统错误 2。找不到指定文件
  18. arcmin 弧分的转换
  19. 2022年中国医疗设备电源市场现状研究分析与发展前景预测报告
  20. Spring源码里开天辟地的五个Bean,再介绍一个学习方法

热门文章

  1. html css web笔记,Web/HTML/CSS/的笔记
  2. VS(官方)跨平台开发远程调试教程(远程开发)
  3. 如何利用LabelImg将标注文件在YOLO格式与PascalVOC格式间相互转换
  4. Python 科学计算库 Numpy (二) —— 索引及切片
  5. linux——系统排错之引导恢复shell
  6. AcWing算法基础课 Level-2 第二讲 数据结构
  7. c语言4x4矩形转置,最快的转置4x4字节矩阵的方法。
  8. java bitset用途_浅谈Java BitSet使用场景和代码示例
  9. orika java_Orika JavaBean映射工具探秘
  10. PHP登录带图片,PHP登录注册完整图片验证码实现