背景
现在项目中要用Linux 平台 接 LCD 单色屏,使用i2c接口,所以和单片机做法是一样的,要自己通过打点函数绘制字体、图形等,此为背景。
我用的字库是GB2312,但是在Linux平台下默认支持是UTF-8的,也为了方便代码管理,所有文件存储为UTF-8格式,这样就引入一个问题,我在Linux下的汉字比如经过转换以后才可以用GB2312的字库接口
字符使用问题
在Linux 下文件以及控制台操作创建的文件默认是utf-8
编码的,现在遇到问题是要绘制字体,字库格式是GB2312的,所以在Linux 环境下的utf-8
字体经过函数调用如果不转码的话,利用GB2312格式显示就是乱码,或者直接把显示汉子的编辑器
编码格式设备GB2312就统一了,总之俩边字库格式一致才行
输出测试
https://www.qqxiuzi.cn/bianma/zhongrihan.php
邢
- 中国国标码
GB2312编码:D0CF
GBK编码:D0CF
GB18030编码:D0CF
- 中国台湾
BIG5编码:A8B7
- 国际码
Unicode编码:90A2
UTF-7编码:2B6B4B492D
UTF-8编码:E982A2
UTF-16编码:FFFEA290
UTF-32编码:FFFE0000A2900000
编码测试
GB2312编码格式 汉字输出
#include <stdio.h>
int main()
{
unsigned char sz[] = "邢";
char *str = sz;
while(*str != '\0'){
printf("%02X ",(*str) & 0xFF);
str += 1;
}
}
输出
D0 CF
utf-8 格式文件 汉字输出
#include <stdio.h>
int main()
{
unsigned char sz[] = "邢";
char *str = sz;
while(*str != '\0'){
printf("%02X ",(*str) & 0xFF);
str += 1;
}
}
输出
E9 82 A2
结论:输出值和理论是一致的!
linux iconv 函数值转化
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iconv.h>
int main()
{
unsigned char *encTo = "GB2312"; //要转换的编码格式
unsigned char *encFrom = "UTF-8"; //原编码格式
//新建一个转换分配描述符
iconv_t cd = iconv_open(encTo, encFrom);
if(cd == (iconv_t)-1)
{
perror("iconv_open");
return -1;
}
//转换的字符串
unsigned char inbuf[256] = "邢";
size_t inbufLen = strlen(inbuf);
//用来保存转换后的字符串
size_t outbufLen = 256;
unsigned char outbuf[outbufLen];
memset(outbuf, 0, outbufLen);
//因为iconv()函数会改变inbuf和outbuf指针,因此实现定义两个临时指针指向于这两,然后用这两个指针去操作
unsigned char *inbufSrc = inbuf;
unsigned char *outbufSrc = outbuf;
//转换之前打印一下原字符串和每个字符串的二进制值
printf("inbuf: %s, len: %ld\n", inbuf, strlen(inbuf));
printf("utf8:\n");
for(int i = 0; i < inbufLen; ++i)
{
printf("%02x ", inbuf[i]);
}
printf("\n\n\n");
//转换
size_t ret = iconv(cd, (char**)&inbufSrc, &inbufLen, (char**)&outbufSrc, &outbufLen);
if(ret == -1)
{
perror("iconv");
iconv_close(cd);
return -1;
}
//打印转换之后的字符串和每个字符串的二进制值(因为outbuf中间会有0,所以不能简单的使用strlen来计算长度)
printf("outbuf: %s len: %ld\n", outbuf, outbufSrc - outbuf);
printf("utf16:\n");
//不能以strlen(outbuf)作为参数2,因为outbuf中间有0,会导致for循环只打印部分的内容
for(int i = 0; i < (int)(outbufSrc - outbuf); ++i)
{
printf("%02x ", outbuf[i]);
}
printf("\n");
//关闭句柄
iconv_close(cd);
return 0;
}
输出
xingzb@ubuntu:~/share$ ./test_iconv
inbuf: 邢, len: 3
utf8:
e9 82 a2
outbuf: en: 2
GB2312:
d0 cf