Qt 5.7 \n behavior - c++

In a Qt 5.7 Console Application:
#include <QCoreApplication>
#include <QtDebug>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QString s = "MDJ\nTest.\n";
qDebug() << "MDJ\nTest.\n";
qDebug() << s;
/* Prints:
MDJ
Test.
MDJ\nTest.\n
*/
return a.exec();
}
i.e. the \n works as expected in a direct debug print, but is treated as just two plain characters when debug printing a (supposedly identical content) variable.
I'm encountering similar problems in Qt 5.7 Widget Applications as well.
I've searched the documentation, stackoverflow, and Qt Centre and I've been unable to discover what I'm doing wrong.
Could somebody please point me to a solution for this?

The docs give you hints:
<< QString()
Normally, QDebug prints the string inside quotes and transforms non-printable characters to their Unicode values (\u1234).
To print non-printable characters without transformation, enable the noquote() functionality. Note that some QDebug backends might not be 8-bit clean.
vs.
<< const char*
Writes the '\0'-terminated string, s, to the stream and returns a reference to the stream. The string is never quoted nor transformed to the output, but note that some QDebug backends might not be 8-bit clean.
Solution: qDebug().noquote() << "some\nspecial\nchars\n\tincluded"

Related

How to print Unicode string using QTextStream?

I want to print Unicode text into Windows console by using Qt (QTextStream). A code page of the console should be set to Unicode by using SetConsoleOutputCP(CP_UTF8) function. However, when I am using a plain way, then the output contains some garbage symbols.
#include <QCoreApplication>
#include <QString>
#include <QTextStream>
#include <QTextCodec>
#include <windows.h>
int main(int argc, char *argv[])
{
SetConsoleCP(CP_UTF8);
SetConsoleOutputCP(CP_UTF8);
QCoreApplication a(argc, argv);
QTextStream stream(stdout);
stream.setCodec("UTF-8");
QString hello = "1 привет 2 привет 3 привет";
stream << hello << endl;
QString hello_en = "1 hello 2 hello 3 hello";
stream << hello_en << endl;
return a.exec();
}
As you can see, after the hello string was printed also garbage symbols were printed, which consisted of part of this string. But the hello_en string consisting only of ASCII symbols was printed correct.
At the same time, if the codec of QTextStream was set to a system locale of console (in my case it is IBM 866), then the garbage symbols were not printed.
#include <QCoreApplication>
#include <QString>
#include <QTextStream>
#include <QTextCodec>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QTextStream stream(stdout);
stream.setCodec("IBM 866");
QString hello = "1 привет 2 привет 3 привет";
stream << hello << endl;
QString hello_en = "1 hello 2 hello 3 hello";
stream << hello_en << endl;
return a.exec();
}
As you see, non-ASCII symbols are printed correctly.
So, when I am trying to use a QTextStream for printing the Unicode string to a Unicode console, then some garbage symbols are appearing in the stdout. Previous questions on Stackoverflow are suggesting a solution without using QTextStream.
What am I doing wrong? Or am I using this correctly and this is a bug in Qt and I should report it to the Qt bug tracker?
UPDATE 1
This issue become on Qt 5.8.0 MinGW 5.3.0 32-bit on Windows 8.1 Pro 64-bit. But, when I tried to use Qt 5.8.0 MSVC2015 on my system, all working well. I am confused. What's wrong? But I can use MSVC2015, because this is not essential.

QTextEdit doesn't display special characters not available on keyboard

I have to display some special characters like ¼, ½ etc. in a QTextEdit which are not on the QWERTY keyboard.I am able to type these characters in the QTextEdit and also able to paste them. But when I try to programatically set these characters QTextEdit displays an extra character 'Â'.
I do not get this problem while typing and pasting. These characters are typed with some Alt+[code] codes.
I am using Qt 4.8 on Windows 8 64bit.
#include<QtGui>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QTextEdit t;
t.setPlainText("¼2½ \n"); // QTextEdit displays=> ¼2½
// t.setHtml("¼2½ \n"); // QTextEdit displays=> ¼2½
// t.insertHtml("¼2½ \n"); // QTextEdit displays=> ¼2½
// t.insertPlainText("¼2½ \n"); // QTextEdit displays=> ¼2½
// also tried setHtml() with HTML code which works in Firefox didn't help me
t.show();
return a.exec();
}
How can I put these characters in a QTextEdit programatically without this extra character?
Your source code needs to be written in UTF-8 encoding, and you should use QStringLiteral in Qt 5 or QString::fromUtf8 in Qt 4. You won't have that problem then.
E.g.:
t.setPlainText(QStringLiteral("¼, ½")); // Qt 5
t.setPlainText(QString::fromUtf8("¼, ½")); // Qt 4
Ensure that the editor you're using is set to encode the file as UTF-8, not Latin 1 etc.
Use QTextCodec to display characters in UTF-8 encoding.
#include <QTextCodec>
...
QTextCodec* codec=QTextCodec::codecForName("UTF-8");
// QTextCodec::setCodecForLocale(codec); //if you want everything to be in UTF-8
QTextCodec::setCodecForCStrings(codec);
QApplication a(argc, argv);
...
Or convert characters in place:
t.setPlainText(QObject::trUtf8("¼2½ \n"));

Printing qByteArray through qDebug

#include <QCoreApplication>
#include <QByteArray>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QByteArray dataReceivedFromSerialPort;
dataReceivedFromSerialPort.push_back(0x0A);
dataReceivedFromSerialPort.push_back(0x0B);
dataReceivedFromSerialPort.push_back(0x0C);
dataReceivedFromSerialPort.push_back(0x0D);
dataReceivedFromSerialPort.push_back(0x0E);
dataReceivedFromSerialPort.push_back(0x0F);
dataReceivedFromSerialPort.push_back(0x07);
dataReceivedFromSerialPort.push_back(0x02);
dataReceivedFromSerialPort.push_back(0x01);
dataReceivedFromSerialPort.push_back(0x02);
qDebug() << "tostr: " << dataReceivedFromSerialPort.toStdString().c_str();
return a.exec();
}
The above does not print any value. It doesn't print anything beyond "tostr: ". If I store 0x0A in uchar and then push it in qByteArray then this problem disappears.
What can I do print it in its current form?
Because the bytes you give are, in many encodings, various control characters (newlines, carriage returns, etc.). Going through std::string and char* means the bytes will be sent as they are to the terminal, and thus displayed that way (either not at all, or as various types of whitespace).
You can try to instead do one of these, depending on what you want:
qDebug() << dataFromSerialPort; // prints "\n\x0B\f\r\x0E\x0F\x07\x02\x01\x02"
qDebug() << QString::fromLatin1(dataFromSerialPort); // prints "\n\u000B\f\r\u000E\u000F\u0007\u0002\u0001\u0002"
qDebug() << dataFromSerialPort.toHex(); // "0a0b0c0d0e0f07020102"
qDebug() << qPrintable(dataFromSerialPort); // same as toStdString().c_str(), but IMO more readable.
These print the bytes in various escape sequences (QString uses unicode, that's why you see \u instead of \x there), as a readable hexadecimal representation as well "as is".
QDebug does special formatting for many known types, like QString and QByteArray, that is why the first three examples above print with quotes and write out the escape sequences (it's for debugging after all). qPrintable, which works very similar to toStdString().c_str() returns a char*, which QDebug does not format in any special way, which is why you get whitespace as the output (this is the same behaviour as std::cout and friends).

NetBeans doesn't output certain ASCII characters

I'm trying to print ASCII characters, but in the output I only see a little box. For example, ASCII 179 is a | character, but it doesn't print. Instead, it prints:
My code:
int main(int argc, char** argv) {
int a[] {179,180,191,192,193,194,195,196,197,217,218,32};
char b = a[2];
std::cout << b;
return 0;
}
How can I resolve this problem?
Note, when I use this code, the output prints the characters correctly:
std::cout << "┐"
But if I use the ASCII character, it prints a box instead.
Edit: To add... even when I output the characters to Notepad, I get the same result.
The problem seems to be an encoding issue. NetBeans by default, is not printing data with UTF-8 encoding.
Take a look at this tutorial to change NetBeans' default encoding.

how to read stdin to end in qt?

I have a qt-app which can be invoked with:
cat bla.bin | myapp
Whats the easiest way to read the entire input (stdin) into a QByteArray on Win,Mac and Linux?
I tired several things, but none of them seems to work (on windows):
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
QByteArray content;
//---Test 1: hangs forever, reads 0
while(!std::cin.eof()) {
char arr[1024];
int s = std::cin.readsome(arr,sizeof(arr));
content.append(arr,s);
}
//---Test 2: Runs into timeout
QFile in;
if(!in.open(stdin,QFile::ReadOnly|QFile::Unbuffered)) {
qDebug() << in.errorString();
}
while (in.waitForReadyRead(1000)) {
content+=in.readAll();
}
in.close();
return app.exec();
}
Am I having a Event-Loop Problem or shouldn't it work without?
The primary problem of actually reading from stdin stems from using readsome. readsome is generally not used to read from files (including stdin). Readsome is generally used for binary data on asynchronous sources. Technically speaking eof doesn't get set with readsome. read is different in that regard as it will set eof accordingly. There is an SO question/answer here that may be of interest. If you are supporting Linux and Windows and reading stdin, you have to be aware that on Windows stdin isn't opened in binary mode (neither is stdout). On Windows you would have to use _setmode on stdin. One way to do this is with #ifdefs using Q_OS_WIN32. Using QFile doesn't resolve this issue.
In the code you are trying to create it doesn't appear you are interested in actually having an event loop. You can still use QT objects like QByteArray without an event loop. In your code you read data in from stdin (cin) and then you executed return app.exec(); which put your console application into a loop waiting for events. You didn't add any events to the QT Event queue prior to app.exec(); so effectively the only thing you can do is end your application with control-c. If no event loop is needed then code like this should suffice:
#include <QCoreApplication>
#include <iostream>
#ifdef Q_OS_WIN32
#include <fcntl.h>
#include <io.h>
#endif
int main()
{
QByteArray content;
#ifdef Q_OS_WIN32
_setmode(_fileno(stdin), _O_BINARY);
#endif
while(!std::cin.eof()) {
char arr[1024];
std::cin.read(arr,sizeof(arr));
int s = std::cin.gcount();
content.append(arr,s);
}
}
Notice how we used a QByteArray but didn't have a QCoreApplication app(argc, argv); and a call to app.exec();