mysql iconv_iconv 用法
iconv 用法
场景说明
将UTF-8的编码转换成GBK编码,使用Notepad++创建一个UTF-8(无BOM)的编码文件,文件内容简单为风雨在途,保存文件名称为utf8.txt,转换之后存储文件名称为gbk.txt.
1.1:iconv命令的使用
iconv -f UTF8 -t GBK gbk.txt
1.2:iconv函数的使用
#include
size_t iconv(iconv_t cd,
char **inbuf, size_t*inbytesleft,
char **outbuf, size_t*outbytesleft);
参数说明:经过iconv函数之后,*outbuf当前指向转换之后的字符串的最后位置,*inuf当前指向被转换字符串的最后位置,所以为了得到正确的转换字符串的指针位置,需要进行如下的调整:
*outbuf = *outbuf - iconv函数的返回值.或者定义指针指向当前的字符串缓存区,就不会修改字符串的缓冲区指针了
1.3代码如下
int UTF8fileToGBKfile()
{
int ret;
int read_fd;
int write_fd;
//1打开文件,读取utf-8文件
read_fd=open("utf8.txt",O_RDONLY|O_CREAT);
write_fd=open("gbk.txt", O_WRONLY|O_CREAT);
char utfBuffer[256] = {0};
size_t inLen = read(read_fd, utfBuffer,256);
//2获取字符集转换的文件句柄,这里是从utf-8转换为gbk
errno = 0;
iconv_t cd = iconv_open("gbk","utf-8");
char* errMsg = NULL;
if (errno !=0)
{
errMsg = strerror(errno);
cout<
cout<
return -1;
}
//3准备转换前的字符串,避免修改原字符串
char* szSrc = (char*)malloc(inLen);
memset(szSrc, 0, inLen);
memcpy(szSrc, utfBuffer, inLen);
//4准备转换后的字符串存储空间
size_t outLen = 256;
char* szDest = (char*)malloc(outLen);
memset(szDest, 0, outLen);
//4开始转换
errno = 0;
char* pszDest = szDest;
char* pszSrc = szDest;
errno = 0;
ret = iconv(cd, &pszSrc, &inLen,&pszDest , &outLen);
if (errno !=0)
{
errMsg = strerror(errno);
cout<
cout<
return -2;
}
iconv_close(cd);
//5写入文件,outlen是剩下多少空间没有使用
ret = write(write_fd, szDest, 256-outLen);
close(read_fd);
close(write_fd);
free(szDest);
free(szSrc);
return 0;
}
2 编译调试
2.1禁用优化安装
下载libiconv-1.14.tar.gz,解压,执行./configure --prefix=/opt/iconv;make;make install
生成文件:
charset.alias libcharset.so libiconv.la libiconv.so.2.5.1
libcharset.a libcharset.so.1 libiconv.so preloadable_libiconv.so
libcharset.la libcharset.so.1.0.0 libiconv.so.2
实际链接到库的时候,指定库目录,在/etc/ld.so.conf文件之后追加一行/opt/iconv/lib.采用ldconfig命令的时候,出错:
libcharset.so.1 不是符号链接
libiconv.so.2 不是符号链接
原因是:删除这两个文件,然后使用ldconfig命令,生成该符号链接。
[root@jack lib]# ll
总用量 3560
-rw-r--r--. 1 root root 212 9月 13 10:22 charset.alias
-rw-r--r--. 1 root root 27868 9月 13 10:22 libcharset.a
-rw-r--r--. 1 root root 936 9月 13 10:22 libcharset.la
-rw-r--r--. 1 root root 277609月 13 10:22 libcharset.so
lrwxrwxrwx. 1 root root 19 9月 13 11:10libcharset.so.1->libcharset.so.1.0.0
-rw-r--r--. 1 root root 27760 9月 13 10:22 libcharset.so.1.0.0
-rw-r--r--. 1 root root 912 9月 13 10:22 libiconv.la
-rw-r--r--. 1 root root 1186436 9月 13 10:22 libiconv.so
lrwxrwxrwx. 1 root root 17 9月 13 11:10 libiconv.so.2 ->libiconv.so.2.5.1
-rw-r--r--. 1 root root 1186436 9月 13 10:22 libiconv.so.2.5.1
-rw-r--r--. 1 root root 1168119 9月 13 10:22 preloadable_libiconv.so
调用该动态库的编译命令如下:
g++ test.cpp -I/opt/iconv/include//opt/iconv/lib/libcharset.a/opt/iconv/lib/libiconv.so libsqlite3.a-lpthread -ldl -g -o main
2.2禁用优化
./configure--prefix=/opt/iconvCFLAGS="-g -O0"
生成动态库链接符号错误解决
[root@jack lib]# ldconfig
ldconfig: /opt/iconv/lib/libiconv.so.2 不是符号连接
ldconfig: /opt/iconv/lib/libcharset.so.1 不是符号连接
[root@jack lib]# rm -rflibiconv.so.2libcharset.so.1
[root@jack lib]# ldconfig
2.3 GDB调试源码
主要是将UTF-8编码的字符串在转换成GBK编码,详细的转换规则UTF-8转Unicode,
然后Unicode编码通过查表,映射到GBK编码上
loop_unicode.h:273
执行函数
incount=cd->ifuncs.xxx_mbtowc(cd,&wc,inptr,inleft);
跳转到./utf8.h:30
核心转换函数:static size_t unicode_loop_convert (iconv_t icd,
const char* * inbuf, size_t *inbytesleft,char* *outbuf,size_t*outbytesleft)
at./loop_unicode.h:284
284 incount = cd->ifuncs.xxx_mbtowc(cd,&wc,inptr,inleft);
at./loop_unicode.h:362
362 outcount = cd->ofuncs.xxx_wctomb(cd,outptr,wc,outleft);
该函数进行Unicode转换成GBK
进行的是查表进行转换,在调试的过程中,可以通过附件,提前知道转换的字符编码,然后查看iconv库是否转换有问题
UTF-8转Unicode编码的函数:
static int
utf8_mbtowc (conv_t conv, ucs4_t*pwc,constunsigned char *s, int n)
iconv函数中传递进去的outptr会指向转换字符串的末尾,所以需要进行指针的前移,outptr-返回值
就是指向最开始转换的字符串
iconv_open函数跳转到lib/iconv.c 218 行,里面调用了
#include "iconv_open1.h"
47-60行
141-152行
for (cp = fromcode, bp = buf, count = MAX_WORD_LENGTH+10+1; ; cp++,bp++){
unsigned char c = * (unsigned char *) cp;
if (c >= 0x80)
goto invalid;
if (c >= 'a' && c <= 'z')
c -= 'a'-'A';
*bp = c;
if (c == '\0')
break;
if (--count == 0)
goto invalid;
}
这里进行了大小写转换,所有的字体编码类型,转换成大写字母,gbk转换成GBK.小写字母转换成大写字母是减去26
目前遇到一个相当大的问题:
ap= aliases_lookup(buf,bp-buf);
if(ap == NULL) {
ap = aliases2_lookup(buf);
if (ap == NULL)
goto invalid;
}
这几行函数没能够单步调试所以并不清楚返回值进行了什么操作
#include "iconv_open2.h"
设置执行的回调函数,以及初始化标志位,具体的没有看出什么
2.4手动编写指令构建动态库
使用库提供的automake,顺利生成libiconv.so文件,目前尝试单独编译,出现如下的问题
使用指令如下:
g++libiconv-1.14/libcharset/lib/localcharset.clibiconv-1.14/lib/iconv.clibiconv-1.14/lib/relocatable.c libsqlite3.a -lpthread -ldl -Ilibiconv-1.14/-I libiconv-1.14/include/-I libiconv-1.14/lib-Ilibiconv-1.14/libcharset/include/ -fPIC -shared -o libiconv.so
libiconv-1.14/libcharset/lib/localcharset.c:77:25:错误:configmake.h:没有那个文件或目录
libiconv-1.14/libcharset/lib/localcharset.c:Infunction‘const char* get_charset_aliases()’:
libiconv-1.14/libcharset/lib/localcharset.c:135:错误:‘LIBDIR’在此作用域中尚未声明
查找资料显示在windows下无需该文件,因此注释该头文件的包含
问题剩下LIBDIR的定义问题
查找所有的引用LIBDIR ,localcharset.c函数
static const char*get_charset_aliases(void)会通过dir =relocate (LIBDIR);
获取该值,查看该函数的内容:
const char *cp;
cp=charset_aliases;
/* Pointer to the contentsofthecharset.alias file, if it has already been
read, else NULL. Its format is:
ALIAS_1 '\0' CANONICAL_1 '\0' ... ALIAS_n '\0'CANONICAL_n '\0''\0' */
static const char *volatilecharset_aliases;
说明指向这个charset.alias文件,查看该文件:
该文件的目录如下:
libiconv-1.14/libcharset/lib
内容如下:
# This file contains a table ofcharacterencodingaliases,
# suitable for operating system'linux-gnu'.
# It was automatically generatedfromconfig.charset.
# Packages using this file:
ISO_646.IRV:1983 ASCII
说明该文件是由同一级目录下的config.charset脚本生成的
跟踪:
linux* | *-gnu*)
#With glibc-2.1 or newer, we don't need any canonicalization,
#because glibc has iconv and both glibc and libiconv support all
#GNU canonical names directly. Therefore, the Makefile does not
#need to install the alias file at all.
#The following applies only to glibc-2.0.x and older libcs.
echo "ISO_646.IRV:1983 ASCII"
翻译:glibc-2.1以后的版本都不需要任何的标准化文件,因为自带的缘故,该文件只是被之前的版本引用
因此在localcharset.c 定义LIBDIR指向的目录:
#defineLIBDIR"/work/libiconv-1.14/libcharset/lib"
[root@jack work]# g++libiconv-1.14/libcharset/lib/localcharset.clibiconv-1.14/lib/relocatable.c libiconv-1.14/lib/iconv.c test.cpp -I libiconv-1.14/ -Ilibiconv-1.14/lib/-Ilibiconv-1.14/include -Ilibiconv-1.14/libcharset/include/ -I libiconv-1.14/srclib/ libsqlite3.a -lpthread -ldl -o testmain
/tmp/cc1ENLex.o: Infunction`libiconv_open':
iconv.c:(.text+0x18206):undefinedreferenceto `aliases_lookup(char const*, unsigned int)'
iconv.c:(.text+0x18391):undefinedreferenceto `aliases_lookup(char const*, unsigned int)'
/tmp/cc1ENLex.o:Infunction`libiconv_open_into':
iconv.c:(.text+0x187d0): undefinedreferenceto`aliases_lookup(char const*, unsigned int)'
iconv.c:(.text+0x1895b):undefinedreferenceto `aliases_lookup(char const*, unsigned int)'
/tmp/cc1ENLex.o: Infunction`iconv_canonicalize':
iconv.c:(.text+0x190a9):undefinedreferenceto `aliases_lookup(char const*, unsigned int)'
collect2: ld 返回 1
该函数的定义就在lib/aliases.h文件当中定义的,不清楚为什么无法找到,
然后手动将该定义拷贝到lib/iconv.c文件,还是出现同样子的问题
mysql iconv_iconv 用法相关推荐
- mysql存储过程知识点_知识点:Mysql 基本用法之存储过程
存储过程 一. 介绍 存储过程包含了一系列可执行的sql语句,存储过程存放于MySQL中,通过调用它的名字可以执行其内部的一堆sql 使用存储过程的优点: 用于替代程序写的SQL语句,实现程序与sql ...
- mysql高级用法(函数)
mysql 高级用法 # CONCAT 函数用于将两个字符串连接为一个字符串 SELECT CONCAT(businfo_name,businfo_creditCode) FROM tb_businf ...
- Mysql Explain用法pdf
<Mysql Explain用法pdf> 下载地址:网盘下载 转载于:https://www.cnblogs.com/long12365/p/9731040.html
- Mysql limit用法
MYSQL limit用法 1.Mysql的limit用法 在我们使用查询语句的时候,经常要返回前几条或者中间某几行数据,这个时候怎么办呢?不用担心,mysql已经为我们提供了这样一个功能. Sql代 ...
- c语言中limit 用法,mysql limit用法及优化详解
摘要 腾兴网为您分享:mysql limit用法及优化详解,一点万象,喜马拉雅,唯品会,图乐等软件知识,以及盟重土城花屏补丁,宝马车主俱乐部,本地文件搜索,锁定刷新率,发券,微信多开真正版,云门禁,真 ...
- 企业级高性能MYSQL的用法---------(二)----------半同步复制 和 全同步复制(组复制)
企业级高性能MYSQL的用法---------(二)----------半同步复制 和 全同步复制(组复制) 1.基于GDIT的半同步复制 为什么要实现mysqI的复制 1.实现服务器负载均衡 2.通 ...
- mysql explain 实例_Mysql实例mysql explain用法学习
<Mysql实例mysql explain用法学习>要点: 本文介绍了Mysql实例mysql explain用法学习,希望对您有用.如果有疑问,可以联系我们. 导读:本节内容:mysql ...
- mysql as用法_MySQL基础学习总结
数据分析无法离开SQL这一重要的工具,经过十天时间的学习,并完全以MySQL工具对上一节的数据分析岗位数据进行了分析,加强了操作训练,对这一工具使用有了基本的经验.本着以输出为手段检验学习效果,以温故 ...
- mysql $的用法_MYSQL limit用法
1.Mysql的limit用法 在我们使用查询语句的时候,经常要返回前几条或者中间某几行数据,这个时候怎么办呢?不用担心,mysql已经为我们提供了这样一个功能. Sql代码 SELECT * F ...
最新文章
- CSS超出部分隐藏,显示滚动条
- OU/Group/Group Policy组织单元、组和组策略
- 《12个球问题》分析
- linux配置接口多地址,Linux /etc/network/interfaces配置接口方法
- 区块链BaaS云服务(17)纸贵科技Z-BaaS零知识证明
- matlab fspeical,matlab的special函数用法
- Python异常处理和进程线程
- 解决mac修改docker容器报错[screen is terminating]
- javascript call与apply关键字的作用
- Raki的读paper小记:NATURAL LANGUAGE INFERENCE OVER INTERACTION SPACE
- Nginx伪静态配置和常用Rewrite伪静态规则
- git学习笔记-(7-高层命令(1))
- 腾讯视频转码,把qlv格式转换成mp4格式
- speedoffice(PPT)插入的表格怎么合并单元格呢
- 如何撰写数据中台蓝图方案
- 为什么要配置hosts来本地测试?
- SpringCloud与微服务Ⅷ --- Hystrix断路器
- Rabbitmq小书
- python在每个字符后加上逗号_Python将逗号添加到数字字符串中
- ubuntu 22.04版本安装