atin-1);
- in Qt 4 the lupdate tool uses the CODECFORTR and CODECFORSRC in your .pro file to know the encoding of the strings inside tr() and of your source files;
- for any other encoding schemes you have to build a proper QTextCodec (by using QTextCodec::codecForName() or similar methods), and then use its toUnicode() method.
QString is a re-entrant, implicitly shared container for an UTF-16 encoded string. This means (in no particular order):
- All methods that take an index, as well as the iterators, work in terms of code units, not code points.
- A QString might contain invalid data (for instance a broken surrogate pair).
But what's wrong with the QString(const char *) constructor?
In Qt 4: that it decodes the bytes in the passed string using the fromAscii() function, which — despite its name — uses the codec returned by QTextCodec::codecForCStrings(), or Latin-1 if you didn't set one. Thus, if you pass UTF-8 data to it without doing anything else, QString is NOT going to decode your data properly.
Note also the codec set is application-wide — once you set it, you change the behaviour of fromAscii() in your code, in libraries you are using, in plugins you may have loaded, etc. If they're very poorly coded you may even break them by doing so (BT;DT).
So what should I use instead?
There are a number of available options:
- Switch all of your code editors to use UTF-8, convert all of your codebase (f.i. by using the iconv(1) tool), set your compiler input and execution charsets to UTF-8, then in your code use QString::fromUtf8(), trUtf8(), etc.; this way, will do the right thing™.
QString str = QStringLiteral("ßàéöø")
- If your source must be 7-bit ASCII, you can still make use of QString::fromUtf8 by either using the u prefix, or performing the encoding by hand and using the escape sequence. Be sure that your execution charset is UTF-8 (or that string literals pass through unchanged). For instance,
QString str = QString::fromUtf8("3\xb7"); // str is "÷"
- If your source is Latin-1 and you don't want to risk it to break if someone changes the codecForCStrings(), you can use the static method QString::fromLatin1().
- QLatin1String (which is thin wrapper around a Latin-1 encoded char *) can also be handy.
Should I use tr() / trUtf8() even if I don't plan to translate my application?
Yes. For instance, you do want to handle plural forms correctly, and not to reinvent the wheel by doing it by hand.
A small digression — what's an encoding?
In information theory, a code is nothing more than a rule — a function — to translate a discrete piece of information (usually, symbols from a source alphabet) into another format of representation (symbols or sequence of symbols of a target alphabet).
The process of converting a symbol from the source alphabet into its associated sequence of symbols of the target alphabet is called encoding; the opposite process is called decoding. We can naturally extend the encoding and the decoding definitions to sequence of symbols of the source alphabet (that is, a string of the source alphabet) into the corresponding sequence made of (sequence of) symbols of the target alphabet.
For instance, a very famous code is the Morse code, which translates letters in the Roman alphabet, Arabic numerals (digits) and some punctuation characters into sequences of dots and dashes.
|B||— . . .|
|9||— — — — .|
There are a certain number of properties that we'd like a code to have: its rule must be an injection, because we don't want to map two different pieces of information into the same representation (we wouldn't know how to translate it back); it should not be unnecessarily verbose ; it could add some error detection and/or error correction schemes ; etc.
A character encoding is no different: it's a rule to translate symbols from (usually) a human alphabet into sequences of bits or bytes. The most famous character encoding is probably US-ASCII, which maps Roman letters, Arabic numerals, punctuation and some control characeters to the numbers in the range 0—127, and thus, requiring 7 bits in binary.
Usually an 