I am doing the following in a C++ source file that is UTF-8 encoded (Qt 5.7, GCC):
QTextStream textStream(&file);
textStream.setCodec("UTF-8");
textStream << "Copyright ©" << endl;
The resulting file is UTF-8 encoded but the ©
characters is not encoded correctly.
This fails because operator<<(const char *string)
expects a Latin-1 string literal. Since the source is UTF-8 this doesn't work.
I also know how to work around this:
QTextStream textStream(&file);
textStream.setCodec("UTF-8");
textStream << QString("Copyright ©") << endl;
This works because QString(const char *str)
expects an UTF-8 string literal.
I need to output a LOT of literal strings this way. I can't wrap all of them into QString()
.
My questions:
1) Why does QString
assume UTF-8 but QTextStream
doesn't? Does this make sense considering Qt sources need to be UTF-8?
2) Is there a way to solve this without hundreds of QString()
wrappers (or similar)?
1) It does seem silly, especially if you take this quote from the documentation into consideration:
Internally, QTextStream uses a Unicode based buffer, and QTextCodec is used by QTextStream to automatically support different character sets.
2) You can inherit from QTextStream
and provide your own operator<<
. I'm not sure whether this is idiomatic Qt, but it works.
struct UnicodedStream : QTextStream
{
using QTextStream::QTextStream;
template<typename T>
UnicodedStream& operator<<(T const& t)
{
return static_cast<UnicodedStream&>(static_cast<QTextStream&>(*this) << t);
}
UnicodedStream& operator<<(char const* ptr)
{
return static_cast<UnicodedStream&>(*this << QString(ptr));
}
};
And if you don't care about using chained calls like x << "foo" << "bar"
, you can use a more simplistic version:
struct UnicodedStream : QTextStream
{
using QTextStream::QTextStream;
using QTextStream::operator<<;
QTextStream& operator<<(char const* ptr)
{
return *this << QString(ptr);
}
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With