日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

Qt QString 中文 char* UTF-8 QByteArray QTextCodec unicode gb2312 GBK 乱码与转码问题

發布時間:2024/9/5 c/c++ 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Qt QString 中文 char* UTF-8 QByteArray QTextCodec unicode gb2312 GBK 乱码与转码问题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

代碼如下:如果不不設全局的字符集是utf-8,那么網上一般的方法是可以轉的。如下程序中 #define DD 1的情況下;但是如果設置了全局的utf-8,再用以前的方法:

QByteArray ba=aaa.toLatin1(); const char *c_str = ba.data(); PS:c_str所指向的內存單元,如果你想長時間使用你應該復制出來,要不可能過數行代碼后,你再讀你的數據,c_str所指向的內存單元就不是你以前讀的內容了。函數返回的指針臨時變量,不能長時間使用!!!!!!! 具體代理在本貼最后補充出來:
等網上類似的方法,都會出現轉代漢字不成功,但能轉代ASICC碼的情況。漢字都成了問號的ASICC碼63。這是因為沒有用對方法沒有用轉換utf-8碼的方法。

轉碼是件很復雜的事。

#include <QtGui/QApplication> #include<QTextCodec> #include<QFont> #include<QtGui> #include <QByteArray> #define DD 0 int main(int argc, char *argv[]) { QApplication app(argc, argv); #if DD //沒有設置全局的是utf-8字符 #else QTextCodec *codec = QTextCodec::codecForName("UTF-8"); QTextCodec::setCodecForLocale(codec); QTextCodec::setCodecForCStrings(codec); QTextCodec::setCodecForTr(codec); QFont font; font.setFamily(("WenQuanYi Zen Hei")); font.setPointSize(12); app.setFont(font); app.setFont(font); #endif QString aaa= "你好a1234"; QString bbb="哈哈afaf394的AAA"; #if DD QByteArray ba=aaa.toLatin1(); const char *c_str = ba.data(); printf("c_str:%s:size=%d\n",c_str,strlen(c_str)); char *p; p=(char *)c_str; printf("p=%d\n",*p); p++; printf("p=%d\n",*p); QString ddd(c_str); qDebug()<<ddd; #else char *ad = aaa.toUtf8().data(); char *bb= bbb.toUtf8().data(); printf("ad=%s,size=%d\n",ad,strlen(ad)); printf("df=%s,size=%d\n",bb,strlen(bb)); #endif QPushButton ccc("AWQ WQ wq 你了"); ccc.show(); return app.exec(); }

以下是在網上找的,感覺很好,可以一塊理解:

這個好像就是用幾種不同的字符,但不會出錯,不像我們一種都搞不定

http://hi.baidu.com/codeworkman/blog/item/5c0d7516c5c03215c83d6dcc.html

Qt QString 中文 char* UTF-8 QByteArray QTextCodec unicode gb2312 GBK

#include <QFile>
#include <QFileDialog>
#include <QTextCodec>
#include <QByteArray>

void MainWindow::on_pushButton_clicked()
{????
??? /*
????? 只有8位編碼的才需要tr, unicode不要tr
????? gb2312是GBK的子集,通常設成哪個都一樣的
????? 所謂的QString轉char*,結果并不相同,根據編碼格式不同而不同
????? QString轉unicode,不用轉,QString本身就是unicode
????? QString的根本是QChar數組,但不是以0結尾,有大小,QChar的根本是ushot
????? Qt中unicode聲明:可以用wchar_t,也可以用ushot,沒有WCHAR
????? QByteArray可以理解為char類型的動態數組,有大小,不是以\0結尾
??? */

??? /*
??????? ui創建1個列表框QListWidget,和1個按鈕即可

??????? 用windows記事本分別創建4種文件,本例可直接打開
??????? ANSI:沒有文件頭,2字節/漢字,1字節/英文
??????? UTF-8:文件頭[0xEF,0xBB,0xBF],3字節/漢字,1字節/英文
??????? Unicode:文件頭[0xFF,0xFE],2字節/漢字,2字節/英文
??????? Unicode big endian :文件頭[0xFE,0xFF],同Unicode,字節序相反

??????? QString轉char*的規則同上;

??? */

??? /*
??? QTextCodec::setCodecForTr(QTextCodec::codecForLocale());
??? QTextCodec::setCodecForTr(QTextCodec::codecForName("gb2312"));
??? QTextCodec::setCodecForTr(QTextCodec::codecForName("GBK"));
??? QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));

??? 如下使用想要得到正確結果必須使用類似以上的語句
??? str = tr("顯示中文");

??? 但以下這個可以直接使用
??? strText = QString::fromLocal8Bit("顯示中文");
??? */

??? ui->list->addItem(QString::fromLocal8Bit("--------顯示中文----------"));

??? QString strFileName = QFileDialog::getOpenFileName(this, tr("OpenFile"), ".", tr("Image Files(*.*)"));
??? if(strFileName.length() == 0)
??? {
??????? ui->list->addItem(tr("You didn't select any files."));
??????? return;
??? }

??? // 打開文件
??? QFile *pFile = new QFile(strFileName);
??? if (!pFile->open(QFile::ReadOnly))
??? {
??????? ui->list->addItem(tr("open file fail %1: %2.").arg(strFileName).arg(pFile->errorString()));
??????? return;
??? }
??? ui->list->addItem(tr("open file ok %1").arg(strFileName));

??? // 讀文件
??? qint64 fileSize = pFile->size();
??? ui->list->addItem(tr("size = %1").arg(fileSize));
??? char *pBuf = new char[fileSize];
??? pFile->read(pBuf, fileSize);
??? pFile->close();

??? if(fileSize < 4)
??? {
???????? ui->list->addItem(tr("fileSize < 4"));
???????? return;
??? }

??? QString strText;
??? uchar *p = (uchar*)pBuf;


??? if(p[0] == 0xEF && p[1] == 0xBB && p[2] == 0xBF)// UTF-8
??? {
??????? ui->list->addItem(tr("UTF-8"));
??????? strText = QString::fromUtf8(pBuf + 3, fileSize - 3);
??? }
??? else if(p[0] == 0xFF && p[1] == 0xFE)// Unicode
??? {
??????? ui->list->addItem(tr("Unicode"));
??????? strText = QString::fromWCharArray((wchar_t*)(pBuf + 2), (fileSize - 2) / 2);
??? }
??? else if(p[0] == 0xFE && p[1] == 0xFF)// Unicode big endian
??? {
??????? ui->list->addItem(tr("Unicode big endian"));
??????? uchar uc = 0;
??????? for(int i = 3; i < fileSize; i += 2)
??????? {
??????????? uc = p[i];
??????????? p[i] = p[i - 1];
??????????? p[i - 1] = uc;
??????? }
??????? strText = QString::fromWCharArray((wchar_t*)(pBuf + 2), (fileSize - 2) / 2);
??? }
??? else??? //ANSI
??? {???????

??????? ui->list->addItem(tr("ANSI"));
??????? strText = QString::fromLocal8Bit(pBuf, fileSize);
??? }

??? ui->list->addItem(strText);

??? QString strMsg, strTmp;

??? //unicode
??? strMsg = tr("unicode: ");
??? QChar *pData = strText.data();
??? for(int i = 0; i < strText.size(); i++)
??? {
??????? strTmp = tr("0x%1, ").arg(QString::number(pData[i].unicode(), 16).toUpper());
??????? strMsg += strTmp;
??? }
??? ui->list->addItem(strMsg);


??? //?gb2312
??? strMsg = tr("gb2312:? ");
??? QByteArray ary1 = strText.toLocal8Bit();
??? uchar *puchar = (uchar*)ary1.data();
??? for(int i = 0; i < ary1.size(); i++)
??? {
??????? strTmp = tr("0x%1, ").arg(QString::number(puchar[i], 16).toUpper());
??????? strMsg += strTmp;
??? }
??? ui->list->addItem(strMsg);

??? //?uft8
??? strMsg = tr("utf-8:?? ");
??? ary1 = strText.toUtf8();
??? puchar = (uchar*)ary1.data();
??? for(int i = 0; i < ary1.size(); i++)
??? {
??????? strTmp = tr("0x%1, ").arg(QString::number(puchar[i], 16).toUpper());
??????? strMsg += strTmp;
??? }
??? ui->list->addItem(strMsg);

??? ui->list->addItem(tr(" "));
}

以下這個我認為是中文字符的深入理解吧:

http://hi.baidu.com/cyclone/blog/item/9d7293130e5a498d6538dbf1.html

QString 與中文問題 2010-07-11 17:04
(更新:本文的姊妹篇?Qt中translate、tr關系 與中文問題?)

首先呢,聲明一下,QString 是不存在中文支持問題的,很多人遇到問題,并不是本身 QString 的問題,而是沒有將自己希望的字符串正確賦給QString。

很簡單的問題,
"我是中文"這樣寫的時候,它是傳統的 char 類型的窄字符串,我們需要的只不過是通過某種方式告訴QString 這四個漢字采用的那種編碼。而問題一般都出在很多用戶對自己當前的編碼沒太多概念,

于是

一個簡 單的 Qt 程序

下面這個小程序,估計大家會感到比較親切。似乎有相當多的中文用戶嘗試寫過這樣的代碼:

#include <QtGui/QApplication>
#include <QtGui/QLabel>

int main(int argc, char **argv)
{
QApplication app(argc, argv);
QString a= "我是漢字";
QLabel label(a);
label.show();
return app.exec();
}

編碼,保存,編譯,運行,一切都很順利,可是結果呢:

  • 多數用戶看到

    其他用戶看到

    ?òê?oo×?

    ??‘??ˉ?±‰? —

出乎意料,界面上中文沒顯示出來,出現了不認識字符。?于是開始用搜索引擎搜索,開始上論壇發帖或抱怨

最后被告知,下面的語句之一可以解決問題:

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

兩條指令挨個一試,確實可以解決(多數用戶是第一條,其他用戶是第二條)。那么,為什么會這樣呢?

兩種亂碼什么時候出現

對這個問題,我想大家可能都有話說。在繼續之前,我們先列個表,看看兩種亂碼分別在那種情況下出現:

我們只列舉大家最常用的3個編譯器(微軟VS的中的cl,Mingw中的g++,Linux下的g++),源代碼分別采用?GBK?和?不帶BOM的UTF-8??以及?帶BOM的UTF-8?這3中編碼進行保存。

  • 源代碼的編碼

    編譯器

    結果

    ?

    GBK

    cl

    1

    *

    mingw-g++

    1

    *

    g++

    1

    ?

    UTF-8(不帶BOM)

    cl

    2

    ?

    mingw-g++

    2

    ?

    g++

    2

    *

    UTF-8(帶BOM)

    cl

    1

    ?

    mingw-g++

    2

    ?

    g++

    編譯失敗

    ?

采用3種不同編碼保存的源代碼文件,分別用3種不同的編譯器編譯,形成9種組合,除掉一種不能工作的情況,兩種亂碼出現的情況各占一半。

從中我們也可以看出,亂碼和操作系統原本是沒有關系的。但我們在 Windows 一般用的GBK,linux一般用的是不帶BOM的UTF-8。如果我們只考慮帶*的情況,也可以說兩種亂碼和系統有關。

QString 為什么會亂碼呢

真的是 QString 亂碼了嗎?我們可以問問自己,我們抱怨的對象是不是搞錯了?

繼續之前,先明確幾個概念:

明確概念0:

  • "我是漢字" 是C語言中的字符串,它是char型的窄字符串。上面的例子可寫為

const char * str = "我是漢字";
QString a= str;

char str[] = "我是漢字";
QString a= str;

明確概念1:

  • 源文件是有編碼的,但是這種純文本文件卻不會記錄自己采用的編碼

這個是問題的根源,不妨做個試驗,將前面的源代碼保存成GBK編碼,用16進制編輯器能看到引號內是ce?d2?ca?c7?ba?ba?d7?d6這樣8個字節。

現在將該文件拷貝到正體(繁體)中文的Windows中,用記事本打開會什么樣子呢?

...
QString a= "扂岆犖趼";
QLabel label(a);
label.show();
...

那么放到歐美人的Windows系統中,再用記事本打開呢?

...
QString a= "?òê?oo×?";
QLabel label(a);
label.show();
...

同一個文件,未做任何修改,但其中的8個字節ce?d2?ca?c7?ba?ba?d7?d6,對用GBK的大陸人,用BIG5的港澳臺同胞,以及用Latin-1的歐洲人看來,看到的卻是完全不同的文字。

明確概念2:

  • 如同我們都了解的'A'與'\x41'等價一樣。

GBK編碼下的

const char * str = "我是漢字"

等價于

const char * str = "\xce\xd2\xca\xc7\xba\xba\xd7\xd6";

當用UTF-8編碼時,等價于

const char * str = "\xe6\x88\x91\xe6\x98\xaf\xe6\xb1\x89\xe5\xad\x97";

注意:這個說法不全對,比如保存成帶BOM的UTF-8,用cl編譯器時,漢字本身是UTF-8編碼,但程序內保存時卻是對應的GBK編碼。

明確概念3:

  • QString 內部采用的是Unicode。

QString內部采用的是 Unicode,它可以同時存放GBK中的字符"我是漢字",BIG5中的字符"扂岆犖趼" 以及Latin-1中的字符"?òê?oo×?"。

一個問題是,源代碼中的這8個字節"\xce\xd2\xca\xc7\xba\xba\xd7\xd6",該怎么轉換成Unicode并存到 QString 內?按照GBK、BIG5、Latin-1還是其他方式...

在你不告訴它的情況下,它默認選擇了Latin-1,于是8個字符"?òê?oo×?"的unicode碼被存進了QString中。最終,8個Latin字符出現在你期盼看到4中文字符的地方,所謂的亂碼出現了

QString 工作方式

const char * str = "我是漢字";
QString a= str;

其實很簡單的一個問題,當你需要從窄字符串 char* 轉成Unicode的QString字符串的,你需要告訴QString你的這串char* 中究竟是什么編碼?GBK、BIG5、Latin-1

理想情況就是:將char* 傳給QString時,同時告訴QString自己的編碼是什么:

就像下面的函數一樣,QString的成員函數知道按照何種編碼來處理 C 字符串

QString QString::fromAscii ( const char * str, int size = -1 )
QString QString::fromLatin1 ( const char * str, int size = -1 )
QString QString::fromLocal8Bit ( const char * str, int size = -1 )
QString QString::fromUtf8 ( const char * str, int size = -1 )

單QString 只提供了這幾個成員函數,遠遠滿足不了大家的需求,比如,在簡體中文Windows下,local8Bit是GBK,可是有一個char串是 BIG5 或 Latin-2怎么辦?

那就動用強大的QTextCodec吧,首先QTextCodec肯定知道自己所負責的編碼的,然后你把一個char串送給它,它就能正確將其轉成Unicode了。

QString QTextCodec::toUnicode ( const char * chars ) const

可是這個調用太麻煩了,我就想直接

QString a= str;

QString a(str);

這樣用怎么辦?

這樣一來肯定沒辦法同時告訴 QString 你的str是何種編碼了,只能通過其他方式了。這也就是開頭提到的

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

設置QString默認采用的編碼。而究竟采用哪一個,一般來說就是源代碼是GBK,就用GBK,源代碼是UTF-8就用UTF-8。但有一個例外,如果你保存成了帶BOM的UTF-8而且用的微軟的cl編譯器,此時仍是GBK。



最后是簡單的編程上的類型轉換,就是具體方法的應用:


http://blog.csdn.net/ghostyu/article/details/6998640

qt學習筆記(三) QString char int之間的轉換


char * 與 const char *的轉換
char *ch1="hello11";
const char *ch2="hello22";
ch2 = ch1;//不報錯,但有警告
ch1 = (char *)ch2;

char 轉換為 QString 其實方法有很多中,我用的是: char a='b';
QString str;
str=QString(a);


QString 轉換為 char
方法也用很多中
QString str="abc";
char *ch;
ch = str.toLatin1.data();


QByteArray 轉換為 char *
char *ch;//不要定義成ch[n];
QByteArray byte;
ch = byte.data();


char * 轉換為 QByteArray
char *ch;
QByteArray byte;
byte = QByteArray(ch);


QString 轉換為 QByteArray
QByteArray byte;
QString string;
byte = string.toAscii();




QByteArray 轉換為 QString
QByteArray byte;
QString string;
string = QString(byte);
這里再對這倆中類型的輸出總結一下:
qDebug()<<"print";
qDebug()<<tr("print");
qDebug()<<ch;(ch 為char類型)
qDebug()<<tr(ch);
qDebug()<<byteArray;(byteArray是QByteArray類型)
qDebug()<<tr(byteArray);
qDebug()<<str;(str 為Qstring類型)
但是qDebug()<<tr(str);是不可以的,要想用tr()函數輸出QString類型的字符則要如下:
qDebug()<<tr(str.toLatin1);


int 轉 QString
int a=10;
QString b;
b=QString::number(a)


QString 轉int
QString a="120"
int b;
b=a.toInt()
char * 與 const char *的轉換
char *ch1="hello11";
const char *ch2="hello22";
ch2 = ch1;//不報錯,但有警告
ch1 = (char *)ch2;


char 轉換為 QString
其實方法有很多中,我用的是:
char a='b';
QString str;
str=QString(a);


QString 轉換為 char
方法也用很多中
QString str="abc";
char *ch;
ch = str.toLatin1.data();


QByteArray 轉換為 char *
char *ch;//不要定義成ch[n];
QByteArray byte;
ch = byte.data();


char * 轉換為 QByteArray
char *ch;
QByteArray byte;
byte = QByteArray(ch);


QString 轉換為 QByteArray
QByteArray byte;
QString string;
byte = string.toAscii();




QByteArray 轉換為 QString
QByteArray byte;
QString string;
string = QString(byte);
這里再對這倆中類型的輸出總結一下:
qDebug()<<"print";
qDebug()<<tr("print");
qDebug()<<ch;(ch 為char類型)
qDebug()<<tr(ch);
qDebug()<<byteArray;(byteArray是QByteArray類型)
qDebug()<<tr(byteArray);
qDebug()<<str;(str 為Qstring類型)
但是qDebug()<<tr(str);是不可以的,要想用tr()函數輸出QString類型的字符則要如下:
qDebug()<<tr(str.toLatin1);


int 轉 QString
int a=10;
QString b;
b=QString::number(a)


QString 轉int
QString a="120"
int b;
b=a.toInt()
另一個


1 QString --> string
QString.toStdString();
2 string --> QString
QString::fromStdString(string)
3 QString --->int,double,char *
QString::toInt()
QString::toDouble()
QString.toStdString().c_str();
4 int double char* --->string
可以采用<sstream>里的stringstream
以int 為例,int a = 3;
stringstream ss;
string strInt;
ss<<a;
ss>>strInt;





開始時所 說的病例程序:

背景都是紅色的代碼作用是相同的,但打出的結果不一樣,后面一個出不了正確的信息,這就是為什么開始說的臨時變量不能長時間使用

#include <QtGui/QApplication> #include "widget.h" #include<QTextCodec> #include<QFont> #include"database.h" #include<QtGui> #include<QPushButton> #include <QByteArray> int main(int argc, char *argv[]) { QApplication app(argc, argv); QTextCodec *codec = QTextCodec::codecForName("UTF-8"); QTextCodec::setCodecForLocale(codec); QTextCodec::setCodecForCStrings(codec); QTextCodec::setCodecForTr(codec); QFont font; font.setFamily(("WenQuanYi Zen Hei")); font.setPointSize(12); app.setFont(font); app.setFont(font); //if(!createConnection()) // return 1 ; QString aaa= "燈開kl"; QString bbb="機頂盒的控制字"; QString ccc = "頻道加" ; #if 0 QByteArray ba=aaa.toLatin1(); const char *c_str = ba.data(); printf("c_str:%s:size=%d\n",c_str,strlen(c_str)); char *p; p=(char *)c_str; printf("p=%d\n",*p); p++; printf("p=%d\n",*p); QString ddd(c_str); qDebug()<<ddd; #else char *ad = aaa.toUtf8().data(); char *bb= bbb.toUtf8().data(); char *cc = ccc.toUtf8().data(); char a1[100],a2[100],a3[100]; memset(a1, 0, sizeof(a1)); memset(a2, 0, sizeof(a2)); memset(a3, 0, sizeof(a3)); strncpy(a1, ad, strlen(ad)); strncpy(a2, bb, strlen(bb)); strncpy(a3, cc, strlen(cc)); printf("ad=%s,size=%d\n",ad,strlen(ad)); printf("df=%s,size=%d\n",bb,strlen(bb)); printf("cd=%s,size=%d\n",cc,strlen(cc)) ; printf("a1=%s,size=%d\n",a1,strlen(a1)); printf("a2=%s,size=%d\n",a2,strlen(a2)); printf("a3=%s,size=%d\n",a3,strlen(a3)); int len1 = strlen(ad) ; int len2 = strlen(bb) ; //qDebug() << ad << len1 << bb << len2 ; #endif QPushButton cccc("AWQ WQ wq 制熱"); cccc.show(); sqlite3 *db; char *zErrMsg ; sqlite3_stmt *stmt; int Codec_Id = 1; if((sqlite3_open("room.db",&db))!=0){ qDebug() << "sqlite3 open is false"; } else{ qDebug() << "sqlite3 open is OK"; } char sql3[100]; int room_Id = 1 ; int Device_Id = 1 ; int Device_Type = 11 ; int Control_Bty = 11 ; int Control_Status = 1 ; int ncols ,rc ; sprintf(sql3,"insert into Codec values(%d,%d,%d,%d,%d,%d,'%s','%s','%s');",Codec_Id,room_Id,Device_Id,Device_Type,Control_Bty,Control_Status,a1,a2,a3); printf("sql3=%s\nlen=%d\n",sql3,strlen(sql3)); sqlite3_exec(db,sql3,NULL,NULL,&zErrMsg); printf("zErrMsg = %s \n", zErrMsg); //檢查插入的數據有沒有問題 memset(sql3,0,sizeof(sql3)) ; sprintf(sql3,"select * from Codec ;") ; int nrow = 0, ncolumn = 0; char **azResult; //二維數組存放結果 sqlite3_get_table(db, sql3,&azResult , &nrow , &ncolumn , &zErrMsg ); int i = 0 ; //printf("size=%d\n",strlen(azResult)); printf( "row:%d column=%d \n" , nrow , ncolumn ); printf( "\nThe result of querying is : \n" ); for( i=0 ; i<( nrow + 1 ) * ncolumn ; i++ ) printf( "size=%d azResult[%d] = %s\n",strlen(azResult[i]), i , azResult[i] ); //釋放掉 azResult 的內存空間 sqlite3_free_table( azResult ); sqlite3_prepare(db,sql3,strlen(sql3),&stmt,NULL); ncols = sqlite3_column_count(stmt); rc = sqlite3_step(stmt); char *name ; while(rc == SQLITE_ROW){ name = (char *)sqlite3_column_text(stmt,0); fprintf(stderr,"Row:Codec_id=%s,%d\n",name,strlen(name)); //L_id 表示是燈的設備表的id rc = sqlite3_step(stmt); } sqlite3_close(db); printf("ad=%s,size=%d\n",ad,strlen(ad)); printf("df=%s,size=%d\n",bb,strlen(bb)); printf("cd=%s,size=%d\n",cc,strlen(cc)) ; return app.exec(); }



總結

以上是生活随笔為你收集整理的Qt QString 中文 char* UTF-8 QByteArray QTextCodec unicode gb2312 GBK 乱码与转码问题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。