Search code examples
qtunicodefirebirdqstringlatin

How to suppress unicode characters in QString or convert to latin1


Trying to insert some data from CSV to Firebird table in Qt. DB is in ASCII. When inserting some strings with non-ascii symbols get error:

Cannot transliterate character between character sets

Setting QSqlDatabase::setConnectOptions("ISC_DPB_LC_CTYPE=UTF8;") and converting column to UTF8 (CHARACTER SET UTF8) does not help - same error. Trying to suppress unicode characters with no luck as well:

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

QString::toLatin1 () does not suppress characters as well. What solution could be here?


Solution

  • This piece of code should do what you need:

    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]));
      }
    }
    

    Here is another, more robust, version:

    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 is just used to show what is extracted. You could copy the data[i] in a char array or a append to a QByteArray.

    result is Honk?????????#asdfe

    This works well for 16bit characters. 32bit characters result in additional '?'s or other characters.