Why are there double quotes when we print using QString? - qt

I am using Qt framework in Linux and a complete beginner.
When I print a simple message like:
qDebug() << "Hello World";
In the Console the output is Hello World.
But if I print the same message like:
QString str = "Hello World";
qDebug() << str;
In the Console the output is "Hello World",(Notice the quotes), How to get the same output using QString?

See QDebug::noquote
Disables automatic insertion of quotation characters around QChar, QString and QByteArray contents and returns a reference to the stream.
When quoting is disabled, these types are printed without quotation characters and without escaping of non-printable characters.
This function was introduced in Qt 5.4.
Usage:
QString str = "Hello World";
qDebug().noquote() << str;
http://doc.qt.io/qt-5/qdebug.html#noquote

you can find the answer in the Qt source code(detail of implementation in the link below) :
https://code.woboq.org/qt5/qtbase/src/corelib/io/qdebug.h.html
you have several definitions of the << operator
from Qt source code :
/*! \fn QDebug &QDebug::operator<<(const char *s)
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.
/ /! \fn QDebug &QDebug::operator<<(const QString &s)
Writes the string, \a s, to the stream and returns a reference to the stream.
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. Output examples: \code QString s; s = "a"; qDebug().noquote()
<< s; // prints: a qDebug() << s; // prints: "a" s = "\"a\r\n\"";
qDebug() << s; // prints: "\"a\r\n\"" s = "\033"; // escape character
qDebug() << s; // prints: "\u001B" s = "\u00AD"; // SOFT HYPHEN
qDebug() << s; // prints: "\u00AD" s = "\u00E1"; // LATIN SMALL LETTER
A WITH ACUTE qDebug() << s; // prints: "á" s = "a\u0301"; // "a"
followed by COMBINING ACUTE ACCENT qDebug() << s; // prints: "aÌ"; s =
"\u0430\u0301"; // CYRILLIC SMALL LETTER A followed by COMBINING ACUTE
ACCENT qDebug() << s; // prints: "аÌ" \endcode
*/
qDebug()<< "hello world" uses QDebug &QDebug::operator<<(const char *s) and not QDebug &QDebug::operator<<(const QString &s) that's why you get the quotes in one version and not the other.
you can get the same result by using :
qDebug().noquote() << s;
on the QString version

Related

How get raw answer data in QWebEngineView?

Next examples work on small html pages, but dont work if page return big html data or json
I try this after loadFinished signal
view->page()->toHtml([cc](const QString &result){
qDebug() << "result ready";
qDebug() << "result string ="<<result;
});
I see "result ready", but second string not print, also I try this:
v->page()->runJavaScript("function jsfun(){return document.getElementsByTagName('html')[0].outerHTML;};");
//v->page()->runJavaScript("alert(jsfun())"); //work correctly
v->page()->runJavaScript("jsfun();",[this](const QVariant &v) {
qDebug() << "result ready";
qDebug() << "result string ="<<v.toString();
});
but again dont see second string
All example work correctly, but if buffer very big qDebug dont print data, you can write data to file or print part of data
Example (call toHtml after loadFinished signal) :
view->page()->toHtml([cc](const QString &result){
QFile file("outerHTML.html");
if(!file.open(QFile::WriteOnly | QFile::Text)){
qDebug() << "Cannot create a file";
return;
}
QTextStream stream(&file);
stream << buff;
file.close();
}

Why JsonCpp library parsing string success, take the string when the program is crash?

I found that the use of JsonCpp library parsed json string A, can not be resolved, the strange thing is that the analysis of string B is resolved successfully, when I take the string content when the program crashes, which is why? How can I avoid the crash?(string A:"http://192.168.1.1";string B:"192.168.1.1";)
#include"include/json/json.h"
#include <iostream>
int main(int argc, char** argv)
{
//compile:g++ -o test json_value.cpp json_writer.cpp json_reader.cpp json_test.cpp -I./include
Json::Value root; // will contains the root value after parsing.
Json::Reader reader;
bool parsingSuccessful = reader.parse( "192.168.1.1", root );//http://192.168.1.1
if ( !parsingSuccessful )
{
// report to the user the failure and their locations in the document.
std::cout << "Failed to parse configuration\n"
<< reader.getFormattedErrorMessages();
return 0;
}
else
{
std::cout << "Successfully parse configuration" << endl;
}
// Get the value of the member of root named 'encoding', return 'UTF-8' if there is no
// such member.
std::string encoding = root.get("encoding", "UTF-8" ).asString();
// And you can write to a stream, using the StyledWriter automatically.
std::cout << "encoding:" <<encoding << endl;
return 0;
}
What JSON do you expect the strings to contain?
Remember that JSON.parse accepts a string containing a valid JSON value.
Neither of the strings you mention are valid JSON values ("192.168.1.1" and "http://192.168.1.1"), it could be that jsoncpp is accepting "192.168.1.1" as a number by ignoring the .1.1 part (if so this is a bug).
If you expect a string you should quote them twice (once for C++ and once for the JSON).
bool parsingSuccessful = reader.parse("\"http://192.168.1.1\"", root);
In this example the first (unescaped) double quotes (") tell C++ this is a string, then the escaped double quotes (\") lets jsoncpp to parse a string variable.
If your compiler supports raw string literals you can avoid escaping the quotes.
bool parsingSuccessful = reader.parse(R"("http://192.168.1.1")", root);
Another example:
bool parsingSuccessful = reader.parse(R("{"a": 42, "b": "hi"})", root);

Comparison in text file using Qt

I am beginner in UI design using Qt. My project now is doing comparison. For example: if I have 2 text file.
How can I compare the number line by line? Because I have so many text file like this, and I need compare them on by one.What I can do now is only read the text file by line order. Thank you so much!
The procedure is simple
Read both files (always make sure they are opened successfully)
Read files line by line and convert strings to numbers for comparison.
Quit if there is no data left.
Moreover, you need to make sure that the format of files is consistent otherwise, you need to make sure what you manipulate is a real number. I assume numbers are integers but of course you can change it. Extra precautions are required in this kind of project. I will leave it to you. The simplified code for the above procedure is
#include <QString>
#include <QFile>
#include <QDebug>
#include <QTextStream>
int main()
{
QFile data1("text1.txt");
if (!data1.open(QIODevice::ReadOnly | QIODevice::Text)){
qDebug() << "text1.txt file can't be opened...";
return -1;
}
QFile data2("text2.txt");
if (!data2.open(QIODevice::ReadOnly | QIODevice::Text)){
qDebug() << "text2.txt file can't be opened...";
return -1;
}
QTextStream in1(&data1), in2(&data2);
while ( !in1.atEnd() && !in2.atEnd() ) {
QString num1 = in1.readLine();
QString num2 = in2.readLine();
if ( num1.toInt() > num2.toInt() )
qDebug() << num1.toInt() << ">" << num2.toInt();
// do the rest of comparison
}
return 0;
}
Now in my case, the txt files are
text1.txt
1
2
3
4
text2.txt
3
5
1
6
The output is
3 > 1
Edit: the OP is looking for the difference and its sum.
int sum(0);
while ( !in1.atEnd() && !in2.atEnd() ) {
QString num1 = in1.readLine();
QString num2 = in2.readLine();
int result = num1.toInt() - num2.toInt();
qDebug() << num1.toInt() << "-" << num2.toInt() << " = " << result;
sum += result;
}
qDebug() << "sum = " << sum;
Basic approach would be something like this:
QString filename1("C:/Users/UserName/Downloads/t1.txt");
QString filename2("C:/Users/UserName/Downloads/t2.txt");
QFile file(filename1);
file.open(QIODevice::ReadOnly);
QTextStream in(&file);
QStringList textOfFile1;
while (!in.atEnd()) {
QString line = in.readLine();
textOfFile1.append(line);
}
QFile file2(filename2);
file2.open(QIODevice::ReadOnly);
QTextStream in2(&file2);
QStringList textOfFile2;
while (!in.atEnd()) {
QString line = in.readLine();
textOfFile2.append(line);
}
if(textOfFile1.size() != textOfFile2) return false;
for(int i = 0; i < textOfFile1.size(); i++)
{
if(textOfFile1[i] != textOfFile2[i]) return false;
}
return true;
i.e. You read the files into a QStringList and you compare the lists line by line. This way you can also catch the firs # of line where there was a mismatch. Note that such comparison also considers white spaces such as \n \t etc.
PS: wrap the readers into functions, to avoid duplication like me. :)
Hope this helps ;)

Why is QString printed with quotation marks?

So when you use qDebug() to print a QString, quotation marks appears suddenly in the output.
int main()
{
QString str = "hello world"; //Classic
qDebug() << str; //Output: "hello world"
//Expected Ouput: hello world
}
I know we can solve this with qPrintable(const QString), but I was just wondering why does QString work like that?, and Is there a method inside QString to change the way it's printed?
Qt 5.4 has a new feature that lets you disable this. To quote the documentation:
QDebug & QDebug::​noquote()
Disables automatic insertion of quotation characters around QChar, QString and QByteArray contents and returns a reference to the
stream.
This function was introduced in Qt 5.4.
See also quote() and maybeQuote().
(Emphasis mine.)
Here's an example of how you'd use this feature:
QDebug debug = qDebug();
debug << QString("This string is quoted") << endl;
debug.noquote();
debug << QString("This string is not") << endl;
Another option is to use QTextStream with stdout. There's an example of this in the documentation:
QTextStream out(stdout);
out << "Qt rocks!" << endl;
Why?
It's because of the implementation of qDebug().
From the source code:
inline QDebug &operator<<(QChar t) { stream->ts << '\'' << t << '\''; return maybeSpace(); }
inline QDebug &operator<<(const char* t) { stream->ts << QString::fromAscii(t); return maybeSpace(); }
inline QDebug &operator<<(const QString & t) { stream->ts << '\"' << t << '\"'; return maybeSpace(); }
Therefore,
QChar a = 'H';
char b = 'H';
QString c = "Hello";
qDebug()<<a;
qDebug()<<b;
qDebug()<<c;
outputs
'H'
H
"Hello"
Comment
So why Qt do this? Since qDebug is for the purpose of debugging, the inputs of various kinds of type will become text stream output through qDebug.
For example, qDebug print boolean value into text expression true / false:
inline QDebug &operator<<(bool t) { stream->ts << (t ? "true" : "false"); return maybeSpace(); }
It outputs true or false to your terminal. Therefore, if you had a QString which store true, you need a quote mark " to specify the type.
Qt 4: If the string contains just ASCII, the following workaround helps:
qDebug() << QString("TEST").toLatin1().data();
Simply cast to const char *
qDebug() << (const char *)yourQString.toStdString().c_str();
one liner no quotes: qDebug().noquote() << QString("string");

How does qDebug() print enum values?

We have a simple piece of code in our application:
void tAccessPoint::OnStateChanged(QAbstractSocket::SocketState state)
{
qDebug() << m_ID << " " << state;
For reasons that aren't important here I was attempting to replace the use of qDebug so I used the code from this post C++ format macro / inline ostringstream. But I was surprised to find that when I do this state no longer appears as a text value but rather as a numeric value. qDebug() seems to know what the name of the enum value is rather than just the value. How does it do this, and can I do the same in my code?
There is no moc magic here, QtNetwork defines explicitly the operator in network/socket/qabstractsocket.h:
QDebug operator<<(QDebug, QAbstractSocket::SocketState) {
switch (state) {
case QAbstractSocket::UnconnectedState:
debug << "QAbstractSocket::UnconnectedState";
break;
case QAbstractSocket::HostLookupState:
debug << "QAbstractSocket::HostLookupState";
break;
case QAbstractSocket::ConnectingState:
debug << "QAbstractSocket::ConnectingState";
break;
case QAbstractSocket::ConnectedState:
debug << "QAbstractSocket::ConnectedState";
break;
case QAbstractSocket::BoundState:
debug << "QAbstractSocket::BoundState";
break;
...
return debug;
}
But you can use QDebug to send the data to a QString inside your function:
QString output;
QDebug(&output) << ...
Maybe this enum to QString convert can be useful :
const QMetaObject & mo = QAbstractSocket::staticMetaObject;
QMetaEnum me = mo.enumerator(mo.indexOfEnumerator("SocketState"));
QString test(me.valueToKey(QAbstractSocket::UnconnectedState));

Resources