How to print string literal and QString with qDebug? - c++

Is there any easy way to get the following work? I mean is there any helper class in Qt which prepares the string for qDebug?
QString s = "value";
qDebug("abc" + s + "def");

You can use the following:
qDebug().nospace() << "abc" << qPrintable(s) << "def";
The nospace() is to avoid printing out spaces after every argument (which is default for qDebug()).

No really easy way I am aware of. You can do:
QByteArray s = "value";
qDebug("abc" + s + "def");
or
QString s = "value";
qDebug("abc" + s.toLatin1() + "def");

According to Qt Core 5.6 documentation you should use qUtf8Printable() from <QtGlobal> header to print QString with qDebug.
You should do as follows:
QString s = "some text";
qDebug("%s", qUtf8Printable(s));
or shorter:
QString s = "some text";
qDebug(qUtf8Printable(s));
See:
http://doc.qt.io/qt-5/qtglobal.html#qPrintable
http://doc.qt.io/qt-5/qtglobal.html#qUtf8Printable

Option 1: Use qDebug's default mode of a C-string format and variable argument list (like printf):
qDebug("abc%sdef", s.toLatin1().constData());
Option 2: Use the C++ version with overloaded << operator:
#include <QtDebug>
qDebug().nospace() << "abc" << qPrintable(s) << "def";
Reference: https://qt-project.org/doc/qt-5-snapshot/qtglobal.html#qDebug

Just rewrite your code like this:
QString s = "value";
qDebug() << "abc" << s << "def";

I know this question is a bit old, but it appears nearly on top when searching for it in the web. One can overload the operator for qDebug (more specific for QDebug) to make it accept std::strings like this:
inline QDebug operator<<(QDebug dbg, const std::string& str)
{
dbg.nospace() << QString::fromStdString(str);
return dbg.space();
}
This thing is for years in all of my projects, I nearly forget it is still not there by default.
After that, usage of << for qDebug() is a lot more usable imho. You can even mix QString and std::string. Some additional(but not really intended) feature is, that you sometimes can throw in integers or other types that allow implicit conversion to std::string .

Related

What is the most appropriate way to concatenate with MFC's CString

I am somewhat new to C++ and my background is in Java. I am working on a hdc printing method.
I would like to know the best practice for concatenating a combination of strings and ints into one CString. I am using MFC's CString.
int i = //the current page
int maxPage = //the calculated number of pages to print
CString pages = ("Page ") + _T(i) + (" of ") + _T(maxPage);
I would like it to look like 'Page 1 of 2'. My current code does not work. I am getting the error:
Expression must have integral or enum type
I have found more difficult ways to do what I need, but I want to know if there is a simple way similar to what I am trying. Thanks!
If that's MFC's CString class, then you probably want Format which is a sprintf-alike for it:
CString pages;
pages.Format(_T("Page %d of %d"), i, maxPage);
i.e. you can assemble the string using regular printf-format specifiers substituting in the numbers at runtime.
You can use also stringstream classes
#include <sstream>
#include <string>
int main ()
{
std::ostringstream textFormatted;
textFormatted << "Page " << i << " of " << maxPage;
// To convert it to a string
std::string s = textFormatted.str();
return 0;
}
std::string has all you need:
auto str = "Page " + std::to_string(i) + " of " + std::to_string(maxPage);
As stated correctly in the comment, you can access the underlying C-string via str.c_str(). Here is a live working example.
If you have C++11 you can use std::to_string: std::string pages = std::string("Page ") + std::to_string(i) + (" of ") + std::to_string(maxPage);
If you don't have C++11 you can use an ostringstream or boost::lexical_cast.

How do I insert a variable result into a string in C++

I just started learning C++ in Qt and I was wondering how can I put a variables result in a string? I'm trying to use this for a simple application where someone puts their name in a text field then presses a button and it displays there name in a sentence. I know in objective-c it would be like,
NSString *name = [NSString stringWithFormatting:#"Hello, %#", [nameField stringValue]];
[nameField setStringValue:name];
How would I go about doing something like this with C++? Thanks for the help
I assume we're talking about Qt's QString class here. In this case, you can use the arg method:
int i; // current file's number
long total; // number of files to process
QString fileName; // current file's name
QString status = QString("Processing file %1 of %2: %3")
.arg(i).arg(total).arg(fileName);
See the QString documentation for more details about the many overloads of the arg method.
You don´t mention what type your string is. If you are using the standard library then it would be something along the lines of
std::string name = "Hello, " + nameField;
That works for concatenating strings, if you want to insert other complex types you can use a stringstream like this:
std::ostringstream stream;
stream << "Hello, " << nameField;
stream << ", here is an int " << 7;
std::string text = stream.str();
Qt probably has its own string types, which should work in a similar fashion.
I would use a stringstream but I'm not 100% sure how that fits into your NSString case...
stringstream ss (stringstream::in);
ss << "hello my name is " << nameField;
I think QString has some nifty helpers that might do the same thing...
QString hello("hello ");
QString message = hello % nameField;
You could use QString::sprintf. I haven't found a good example of it's use yet, though. (If someone else finds one, feel free to edit it in to this answer).
You might be interested in seeing information about the difference between QString::sprintf and QString::arg.

How to call qDebug without the appended spaces and newline?

I'm using the the C++/Qt print function qDebug,
but sometimes I would like to control how ", space and newline is appended
and not use the default qDebug.
Let's take a simple example:
QString var1("some string");
int var2 = 1;
qDebug() << var1 << "=" << var2;
This will print
"some string" = 1
But Let's say that I don't like the appended " and space
and would like the print to look like
some string=1
How to I then call qDebug?
Note: There is a function in qDebug called nospace, but it will remove the spaces.
But the " is still there.
If I use this:
qDebug().nospace() << var1 << "=" << var2;
I get:
"some string"=1
But please note that I have still not found a way to get rid of the ending newline.
/Thanks
It would be best to understand how QDebug works internally. That way you can easily modify it to suit your needs. Whenever you use the qDebug() function, it returns a QDebug object. By default QDebug always outputs a space after any use of operator <<.
The QDebug class internally contains a QString. Every time you use operator << you are appending to that internal QString. This QString is printed via qt_message_output(QtMsgType, char*) when the QDebug object is destroyed.
By default qt_message_output always prints the string followed by a newline.
Normal Output
qDebug() << "Var" << 1;
This will output Var 1. This is because qDebug will create a QDebug object which appends a space after each call to operator <<. So that will be Var + + 1 + .
Without Spaces
You can use QDebug::nospace to tell QDebug not to append a space after each call to operator <<.
qDebug().nospace() << "Var" << 1;
This will output Var1 as that QDebug object is no longer printing spaces.
Without New Lines
Not adding the \n at the end of the string is a little bit harder. Since QDebug internally only passes the string to qt_message_output when it is destroyed, you can delay the destruction of that QDebug object -
QDebug deb = qDebug();
deb << "One" << "Two";
deb << "Three";
This will print One Two Three and then append a new line.
If you never want a new line to be printed, you will have to change the behaviour of qt_message_output. This can be done by installing a custom handler.
void customHandler(QtMsgType type, const char* msg) {
fprintf(stderr, msg);
fflush(stderr);
}
// Somewhere in your program
qInstallMsgHandler(customHandler);
qDebug() << "One" << "Two";
qDebug().noSpace() << "Three" << "Four";
This will print One Two ThreeFour.
Be warned that this will affect all of the qDebug statements in your program. If you want to remove the custom handler, you should call qInstallMsgHandler(0).
qDebug(const char* msg, ...)
As indicated by the other answers you can also use the qDebug function to print strings in a format similar to that of printf. This way you can avoid the extra spaces that are appended by QDebug.
However, qDebug internally still uses qt_message_output, so you will still get a newline at the end unless you install your own handler.
Try this format: qDebug("%s=%d", "string", 1);
In this case qDebug uses printf formatting
P.S. Adapted for your example: qDebug("%s=%d", var1.toStdString().c_str(), var2);
Since Qt 5.4 you can also write:
qDebug().nospace().noquote() << var1;
Combining some of the above answers you can use
qDebug() << qPrintable(var1);
to eliminate the surrounding quotes.
I also experienced the quotes problem. The solution is to not pipe QString() into the stream but instead QString(...).toStdString().c_str().
I've built myself a small convenience macro to easily get around this:
#define Q(string) (string).toStdString().c_str()
Now everytime you use a QString, do it like that:
qDebug() << Q(var1) << "=" << var2;
The file $(QTDIR)/src/corelib/io/qdebug.h contains almost all definitions for the debug output methods. One of them is:
inline QDebug &operator<<(const QString & t) { stream->ts << '\"' << t << '\"'; return maybeSpace(); }
So there is no "official" way to suppress the quotes, but you can of course change qdebug.h or use your own copy or a modified and renamed copy of the QDebug class.
Another way is to use your own message handler.
Hope this helps.
Instantiate a QDebug object and output to it:
QDebug dbg = qDebug().nospace().noquote();
dbg << var1 << "=" << var2;
Yields:
some string=1
Output to the dbg object all you want -- there won't be a newline until it goes out of scope. For example:
char var1[] = "some string";
int var2 = 1;
{
QDebug dbg = qDebug().nospace().noquote();
dbg << var1 << "=" << var2;
// keep using "dbg"; there's no newline ('\n') until it destructs
dbg << "...";
for (int i = 5; i <=9; ++i)
dbg << i;
}
Outputs:
some string=1...56789

QString, remove labels and content?

message.Text() is a QString.
I want to remove some text.
The text can be:
Normal: "This is a text"
With a label: "<label1>something</label1>This is a text"
First, I find if the text has the label:
!message.Text().contains("<label1>", Qt::CaseInsensitive))
So, if it has, I want to remove the first part, to have a normal text "This is a text".
I tried this:
first=message.Text().indexOf("<label1>");
last=message.Text().lastIndexOf("</label1>");
message.Text().remove(first,last);
But I got Compiler Error C2663.
I also know that the message.Text().remove(QChar('<label1'), Qt::CaseInsensitive); is another way to do it. But in my case, the part between the label is unkwnow.
It can be <label1>something</label1> or <label1>oisdioadj</label> or <label1>7</label1>....
Any idea?
Regards.
Try the following:
#include <iostream>
using std::cout; using std::endl;
#include <QString>
int main()
{
QString message = "<label1>something</label1>This is a test";
const QString labelClose = "</label1>";
const int labelCloseSize = labelClose.size();
cout << "message: " << qPrintable(message) << endl;
const int closePosition = message.lastIndexOf(labelClose);
QString justText = message.remove(0, closePosition + labelCloseSize);
cout << "just text: " << qPrintable(justText) << endl;
}
My advice here: keep things simple in your code, it will help making things simple in your head.
It seems what you want to achieve is more related to strings, than to label.
I suggest you get the text from your label, then work on it independently, then associate it back to your label:
QString text = message.text();
/* Do whatever you need to do here with text */
message.setText(text);
Also, the error you're having is probably due to the fact that you try to modify directly message.text() which is a const reference: obviously you can't modify something that is const.
I believe what you try to achieve can be done using QString::replace(). You'll have to use regular expressions for that, so if you're not familiar with it, it might be difficult.

How to convert int to QString?

Is there a QString function which takes an int and outputs it as a QString?
Use QString::number():
int i = 42;
QString s = QString::number(i);
And if you want to put it into string within some text context, forget about + operator.
Simply do:
// Qt 5 + C++11
auto i = 13;
auto printable = QStringLiteral("My magic number is %1. That's all!").arg(i);
// Qt 5
int i = 13;
QString printable = QStringLiteral("My magic number is %1. That's all!").arg(i);
// Qt 4
int i = 13;
QString printable = QString::fromLatin1("My magic number is %1. That's all!").arg(i);
Moreover to convert whatever you want, you can use QVariant.
For an int to a QString you get:
QVariant(3).toString();
A float to a string or a string to a float:
QVariant(3.2).toString();
QVariant("5.2").toFloat();
Yet another option is to use QTextStream and the << operator in much the same way as you would use cout in C++:
QPoint point(5,1);
QString str;
QTextStream(&str) << "Mouse click: (" << point.x() << ", " << point.y() << ").";
// OUTPUT:
// Mouse click: (5, 1).
Because operator <<() has been overloaded, you can use it for multiple types, not just int. QString::arg() is overloaded, for example arg(int a1, int a2), but there is no arg(int a1, QString a2), so using QTextStream() and operator << is convenient when formatting longer strings with mixed types.
Caution: You might be tempted to use the sprintf() facility to mimic C style printf() statements, but it is recommended to use QTextStream or arg() because they support Unicode strings.
I always use QString::setNum().
int i = 10;
double d = 10.75;
QString str;
str.setNum(i);
str.setNum(d);
setNum() is overloaded in many ways. See QString class reference.
A more advanced way other than the answer of Georg Fritzsche:
QString QString::arg ( int a, int fieldWidth = 0, int base = 10, const QChar & fillChar = QLatin1Char( ' ' ) ) const
Get the documentation and an example here.
If you need locale-aware number formatting, use QLocale::toString instead.
Just for completeness, you can use the standard library and do:
QString qstr = QString::fromStdString(std::to_string(42));
QLocale has a handy way of converting numbers.  It's not much more typing than the accepted answer, but is more useful in the case of floats; so I like to do both this way.  Here's for an int:
int i = 42;
QString s = QLocale().toString(i);
and here's for a float:
float f=42.5;
QString s = QLocale().toString(f, 1);
the last argument is the number of decimal places.  You can also insert a char format argument such as 'f' or 'e' for the second parameter. The advantage of this, is if your program is then run in a locale where a comma is used as a decimal "point", it will automatically print it that way.  It's not included in something like <QCoreApplication>, so you'll have to do an #include <QLocale> somewhere, of course.  It really comes into its own in formatting currency strings.
It has the slight performance downside of requiring the creation and deletion of an object during the evaluation, but were performance an issue, you could just allocate it once, and use it repeatedly.
You could write:
QString s = QString::number(42.5, 'f', 1);
but according to the help "Unlike QLocale::toString(), this function does not honor the user's locale settings."