【Qt-编码】

Qt编程指南

  • [■ 编码](#■ 编码)
    • [■ ASCII](#■ ASCII)
    • [■ ANSI](#■ ANSI)
    • [■ GB2312](#■ GB2312)
    • [■ GBK](#■ GBK)
    • [■ GB18030 编码](#■ GB18030 编码)
    • [■ Unicode](#■ Unicode)
    • [■ UTF-8:](#■ UTF-8:)
  • [■ Qt接收注射泵GBK编码后显示乱码](#■ Qt接收注射泵GBK编码后显示乱码)

■ 编码

■ ASCII

(American Standard Code for Information Interchange,美国信息交换标准代码)

使用7位(bits)表示一个字符,共128字符;但是7位编码的字符集只能支持128个字符,为了表示更多的欧洲常用字符对ASCII进行了扩展,ASCII扩展字符集使用8位(bits)表示一个字符,共256字符。

Latin-1:(相当于ASCII+标准的扩展ASCII)

即ISO-8859-1的别名,编码是单字节编码,向下兼容ASCII,其编码范围是0x00-0xFF,0x00-0x7F之间完全和ASCII一致,0x80-0x9F之间是控制字符,0xA0-0xFF之间是文字符号。比ASC多了西欧语言、希腊语、泰语、阿拉伯语、希伯来语对应的文字符号。所以中文字符会显示为是西欧等字符"ÎÒÊÇ"

■ ANSI

不同的国家和地区制定了不同的标准,由此产生了 GB2312、GBK、GB18030、Big5、Shift_JIS 等各自的编码标准。

这些使用多个字节来代表一个字符的各种汉字延伸编码方式,称为 ANSI 编码。

在简体中文Windows操作系统中,ANSI 编码代表 GB2312编码;

在繁体中文Windows操作系统中,ANSI编码代表Big5;

在日文Windows操作系统中, ANSI 编码代表 JIS 编码。

不同 ANSI 编码之间互不兼容,当信息在国际间交流时,无法将属于两种语言的文字,存储在同一段 ANSI 编码的文本中。

ANSI编码表示英文字符时用一个字节,表示中文用两个或四个字节。

■ GB2312

GB2312标准共收录6763个汉字,其中一级汉字3755个,二级汉字3008个;

GB2312对任意一个图形字符都采用两个字节表示,并对所收汉字进行了"分区"处理,每区含有94个汉字/符号,分别对应第一字节和第二字节。

对于人名、古汉语等方面出现的罕用字,GB2312不能处理,这导致了后来GBK 及GB18030 汉字字符集的出现。

■ GBK

GBK全称《汉字内码扩展规范》 中华人民共和国全国信息技术标准化技术委员会1995年12月1日制订

GBK 向下与 GB 2312 编码兼容,向上支持 ISO 10646.1国际标准

GBK共收入21886个汉字和图形符号。

GBK采用双字节表示,总体编码范围为8140-FEFE之间,首字节在81-FE之间,尾字节在40-FE之间。

■ GB18030 编码

与 GBK 不同的是,GB18030 是变长多字节字符集,每个字或字符可以由一个,两个或四个字节组成,所以它的编码空间是很大的,最多可以容纳 161 万个字符

由于需要兼容 GBK,四个字节的前两个字节和 GBK 编码保持一致,GB18030 具体的编码范围如下

// GBK编码和UTF-8编码互相转换的函数。返回值是QString, 验证ok

cpp 复制代码
inline QString GBK2UTF8(QByteArray &inStr)
{
    QTextCodec *gbk = QTextCodec::codecForName("gbk");
    QTextCodec *utf8 = QTextCodec::codecForName("UTF-8");
    char *p = inStr.data();
    QString str = gbk->toUnicode(p);
    QByteArray utf8_bytes=utf8->fromUnicode(str);
    p = utf8_bytes.data();
    str = p;
    return str;
}

inline QString UTF82GBK(QByteArray &inStr)
{
    QTextCodec *gbk = QTextCodec::codecForName("gbk");
    QTextCodec *utf8 = QTextCodec::codecForName("UTF-8");
    char *p = inStr.data();
    QString str = utf8->toUnicode(p);
    QByteArray utf8_bytes=gbk->fromUnicode(str);
    p = utf8_bytes.data();
    str = p;
    return str;
}
cpp 复制代码
//根据上面代码优化 实现和云平台对接不乱码问题。
/*将GBK编码转换成UTF-8编码,返回值是QString*/
//说明 m_realdata.drugname[20] 是泵的GBK编码。
QByteArray gdkStr((char*)m_realdata.drugname);
QTextCodec *gbk = QTextCodec::codecForName("gbk");
QTextCodec *utf8 = QTextCodec::codecForName("UTF-8");
QString gbkstring = gbk->toUnicode(gdkStr);
QByteArray utf8_bytes=utf8->fromUnicode(gbkstring);
return utf8_bytes; 
c 复制代码
//GBK‐> QString  unicode
uint8_t utf8[] = {0xCA ,0xB9, 0xD3, 0xC3, 0xCA, 0xE4, 0xD2 ,0xBA, 0xC6, 0xF7, 0x3A, 0x57, 0x45, 0x49, 0x47, 0x41, 0x4F};
QString str2 = QString::fromLocal8Bit((char*)utf8);  //QT默认的编码是unicode,不能显示中文的 实现了从本地字符集GBK到Unicode的转换,
qDebug() << str2 << endl; //使用输液器:WEIGAO 

//stFrame->data[5] 是GB2312 十六进制数据,通过一下转写入到U盘文件中,可以查看不乱码。
QString recordData = QString::fromLocal8Bit((const char*)&stFrame->data[5],stFrame->head.len-5); //实现了从本地字符集GBK到Unicode的转换,

/*末尾添加*/
void CsvFile::tailAppendCsvLine(QString &content)
{
    file.atEnd();
    content += \n;
    file.write(content.toLocal8Bit().data()); 、、写入文件后可以显示中文
    file.flush();
}
c 复制代码
QString qstr;
QByteArray qbytea1 = qstr.toLatin1();    //Latin1代表ASCII  ISO-8859-1编码是单字节编码,向下兼容ASCII,其编码范围是0x00-0xFF。亦称为Latin1。
QByteArray qbytea2 = qstr.toUtf8();      //utf8字符集以2个或以上的字节表示一个汉字。
QByteArray qbytea3 = qstr.toLocal8Bit(); //Local8Bit代表unicode unicode字符集以2个或以上的字节表示一个汉字。
QString(const char *str)   //char*字符串,默认这个字符串是以utf-8编码的.
QString::fromUtf8  

QString s1 = u8中国;
QString s2 = QString::fromUtf8(u8中国);
std::string stdS = u8中国;
QString s3 = QString::fromStdString(stdS); //QString::fromStdString也是将std::string中的字符串当做utf-8编码来处理的。
qDebug() << s1 << s2  << s3  << endl;  //中国 中国 中国 

/* 转换为字节数组 */
QString s1 = "我是中文";
QString s2("我是中文");
QString s3;
s3 = "我是中文"
s1、s2 用的是QString的构造函数QString ( const char * str )
s3 用的是QString的赋值操作符 QString & operator= ( const char * str)

如果不指定编码,s1,s2,s3将全部都是(国内大多数人所称的)乱码。因为QString将这些const char *按照latin1来解释的,而不是用户期待的gbk或utf8。

QTextCodec::setCodecForCStrings(QTextCodec::codecForName("GB2312"));
QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"))

■ Unicode

Unicode只是一种编码规范,而实现方式就有:utf8,utf16,utf32等。

Unicode是一种字符编码,它为每个字符分配了一个唯一的数字,无论平台、程序或语言如何,都可以使用相同的数字来表示该字符。Unicode支持超过100,000个字符,包括世界上所有的语言、符号和表情。Unicode编码通常用于国际化应用程序和网站,以确保它们可以在全球范围内使用。

■ UTF-8:

UTF-8是一种Unicode编码方式,它使用1到4个字节来表示每个字符。UTF-8是一种变长编码方式,它可以表示Unicode标准中的任何字符,而且也是互联网上最常用的编码方式之一。

■ Qt接收注射泵GBK编码后显示乱码

cpp 复制代码
//QTextCodec 可以用于将一些本地编码的字符串转换为 Unicode
QByteArray encodedString = "中国";
QTextCodec *codec = QTextCodec::codecForName("GBK");
QString string = codec->toUnicode(encodedString);  //将 encodedString为GBK编码转换成Unicode编码.

//将字符串从 Unicode 转换为本地编码:
 QString string = "中国";
 QTextCodec *codec = QTextCodec::codecForName("GBK");
 QByteArray encodedString = codec->fromUnicode(string); //将 string为Unicode编码转换成GBK编码.

示例一:

/*正确GBK转换Unicode*/
QTextCodec *codec = QTextCodec::codecForName("GBK");
QString stre = codec->toUnicode((char*)ps.name);
QString strd = codec->toUnicode((char*)ps.department);
QString strh = codec->toUnicode((char*)ps.hospnum);
sethospnum(stre);    //中国
setdepartment(strd); //中国
setbedname(strh);    //中国

/*乱码*/
QString qhospnum(QString::fromLocal8Bit((char*)ps.hospnum,MAX_NAME_LENGTH));
QString qdepartment(QString::fromLocal8Bit((char*)ps.department,MAX_NAME_LENGTH));
QString qname(QString::fromLocal8Bit((char*)ps.name,MAX_PATIN_NAME_LENGTH));
setname(qname);         //乱码
setweight(qdepartment); //乱码
setBMI(qhospnum);       //乱码

/*正确Unicode转换 GBK*/
QTextCodec *codec = QTextCodec::codecForName("GBK");
QByteArray Array1 =codec->fromUnicode(hospnum());
memcpy(pfors.hospnum,Array1.data(),qMin(Array1.size(),MAX_NAME_LENGTH));

QByteArray Array2 =codec->fromUnicode(department());
memcpy(pfors.department,Array2.data(),qMin(Array2.size(),MAX_NAME_LENGTH));

QByteArray Array3 =codec->fromUnicode(name());
memcpy(pfors.name,Array3.data(),qMin(Array3.size(),MAX_PATIN_NAME_LENGTH));

cpp 复制代码

cpp 复制代码
相关推荐
Code成立30 分钟前
1、深入理解Redis线程模型
数据库·redis·bootstrap
缘友一世2 小时前
macos安装mongodb
数据库·mongodb·macos
万事大吉CC4 小时前
mysql单表查询·3
数据库·mysql
bin91534 小时前
【EXCEL数据处理】000010 案列 EXCEL文本型和常规型转换。使用的软件是微软的Excel操作的。处理数据的目的是让数据更直观的显示出来,方便查看。
大数据·数据库·信息可视化·数据挖掘·数据分析·excel·数据可视化
Miqiuha5 小时前
lock_guard和unique_lock学习总结
java·数据库·学习
一律清风6 小时前
QT-文件创建时间修改器
c++·qt
一 乐6 小时前
学籍管理平台|在线学籍管理平台系统|基于Springboot+VUE的在线学籍管理平台系统设计与实现(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端·学习
不知所云,6 小时前
qt cmake自定义资源目录,手动加载资源(图片, qss文件)
开发语言·qt
Death2007 小时前
Qt 6 相比 Qt 5 的主要提升与更新
开发语言·c++·qt·交互·数据可视化
机器视觉知识推荐、就业指导7 小时前
使用Qt实现实时数据动态绘制的折线图示例
开发语言·qt