【问题标题】:How to suppress unicode characters in QString or convert to latin1如何抑制 QString 中的 unicode 字符或转换为 latin1
【发布时间】:2016-03-06 08:18:53
【问题描述】:

尝试将一些数据从 CSV 插入 Qt 中的 Firebird 表。 DB 是 ASCII 格式。插入一些带有非 ascii 符号的字符串时会出错:

无法在字符集之间音译字符

设置 QSqlDatabase::setConnectOptions("ISC_DPB_LC_CTYPE=UTF8;") 并将列转换为 UTF8 (CHARACTER SET UTF8) 没有帮助 - 同样的错误。尝试抑制 unicode 字符也没有运气:

    QTextCodec *codec = QTextCodec::codecForName("latin1");
    QByteArray encodedString = codec->fromUnicode(str);
    str = QString(encodedString);

QString::toLatin1 () 也不会抑制字符。这里有什么解决方案?

【问题讨论】:

  • 奇怪,ALTER TABLE <tablename> ALTER COLUMN <column> TYPE VARCHAR(x) CHARACTER SET UTF8 没有改变列字符集,仍然是 ASCII。
  • QString 已经在 utf-16 中,您的转换将删除所有非 7 位 ascii 字符并且它没用。 FireBird 的输出数据类型是什么?显示代码,第一次填写str 的方式。
  • 对不起,我不清楚,你想实现什么?您需要剥离所有非 ASCII 字符吗?你在找doc.qt.io/qt-5/qstring.html#toLatin1 吗?
  • 我有 Qt 4,但它不起作用 - 不抑制字符,toAscii()toLatin() 也不起作用。
  • 查询:INSERT INTO RXNORM_INGREDIENTS (RXCUI, RXAUI, STR) VALUES ('151513', '2355753', 'CinaziГЁre') 数据库文本:算术异常、数字溢出或字符串截断 - 无法在字符集之间转写字符驱动程序文本:无法执行查询

标签: qt unicode firebird qstring latin


【解决方案1】:

此代码从 qstring(16 位或 32 位)中提取任何 unicode(表情符号),toReturn 仅包含 ASCII 表中的字符(unicode 值小于 256)

QString cleanQString(QString toClean) {

    QString toReturn="";

    for(int i=0;i<toClean.size();i++){
        if(toClean.at(i).unicode()<256){
            toReturn.append(toClean.at(i));
        }
    }

    return toReturn;


}

【讨论】:

    【解决方案2】:

    这段代码应该做你需要的:

    QString h("Honkäüö?ß#asdfe");
    
    unsigned char * data = (unsigned char*)h.data();
    
    QString result;
    
    for(int i = 0; h.size()*2; i+=2) {
       if(data[i] > 127) {
         result.append("?");
      } else {
         result.append(QChar(data[i]));
      }
    }
    

    这是另一个更强大的版本:

    QString h("Honkäüö?ß#asdfe");
    QString result;
    
    for(int i = 0; i < h.size(); ++i) {
       QChar qc = h.at(i);
       unsigned char c = *(unsigned char*)(&qc);
       if(c >= 127) {
         result.append("?");
       } else if (QChar(c).isPrint()) {
         result.append(QChar(c));
       }
    }
    

    QString result 仅用于显示提取的内容。您可以将data[i] 复制到char 数组中或附加到QByteArray

    resultHonk?????????#asdfe

    这适用于 16 位字符。 32 位字符会产生额外的 '?' 或其他字符。

    【讨论】:

    • 好主意,如果没有找到更好的方法会尝试。将 chars > 127 替换为 ?或者像这样。用德语变音符号 'Ä' 替换字符很好,例如像 'A' 这样有意义。
    • 不应将 utf-16 数据转换为 8 位,因为 utf-16 字符可能具有可变长度。
    • 没错,我在最后一句话中说明了这个事实。
    • @SaZ 这不是风险,不会使这种方法无用,当然也不能证明投反对票是合理的。
    • 似乎上面的答案是目前唯一的方法:Firebird 不允许更改列/表/数据库代码页,仅适用于较新创建的数据。
    猜你喜欢
    • 1970-01-01
    • 2011-07-23
    • 2011-07-14
    • 2011-07-21
    • 1970-01-01
    • 1970-01-01
    • 2011-02-15
    • 2010-12-04
    • 1970-01-01
    相关资源
    最近更新 更多