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

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.

Related

How to efficiently create const c string from string literal and appended int or long value

In c++ how can I efficiently create a c string based on a literal and appended long/int value? I logically want to do something like this:
const char *sql = "select * from MyTable where ID = " + longId;
Where longId is an int/long parameter.
This compiles an answer from user4581301 comment and I offer to delete if user4581301 makes their own answer and asks me to.
As suggested by user4581301, you can do:
std::string s = "select * from MyTable where ID = " + std::to_string(longId);
You can get a C string equivalent using s.c_str(), e.g.:
std::cout << s.c_str() << std::endl;
I think the answer from H.S. is perfect, given the question asked. Just a quick FYI, since I'm using Qt (which I didn't mention in the OP), I ended up using this code:
QString sql = QStringLiteral("SELECT v.drive_path_if_builtin, "
"m.full_filepath "
"FROM media_table m "
"INNER JOIN volume_table v "
"ON (v.id = m.volume_id) "
"WHERE m.id = %1;").arg(id);
... and then in the appropriate place, where I need a c-string, I used qPrintable(sql).

How to add current time to a string concisely in C++?

I'd like to add a timestamp to the filename in this part of my code:
takeScreenshot( "screenshot.png" );
But all ways of doing this that I've found seem unnecessarily long and complicated. E.g. creating a new string, loading a time struct, converting an element of the time struct to a char array and appending it to the string.
Is there a short way to accomplish this? Most other languages would have some simple solution like:
takeScreenshot( sprintf( "screenshot-%d.png", time() ) );
Is there one in C++? The time format doesn't matter.
Concatenating a string is long and complicated, under the hood.
A nice way is to use std::stringstream which overloads << for concatenation:
std::stringstream ss;
ss << "screenshot-" << time() << ".png";
std::string s = ss.str();
and format time() to personal taste.
You can use stringstream or just use + operator between strings:
takeScreenshot("screenshot-" + time() + ".png");

how do you pass in string with a string variable to a function in C++

I have a function with default Parameters which displays text to screen. Something like this:
DrawScreenString(int, int, string, int uicolor, font);
I am however trying to pass in a string variable "livesRemaining" like so:
DrawScreenString(10, 5, "Lives : %d ",livesRemaining, 0xF14040, NULL);
livesRemaining = 3
So due to the fact that the function only takes in 5 arguments, it fails to compile, because the function thinks that i'm trying to pass in a 6th argument not knowing i'm trying to add string to the already existing string "Lives :"
This is what i want the result to look like:
Live : 3
I know this is not the right way of doing this, how do i do it ?
Thanks a bunch !!
If you are using a compiler with c++11 support in it, you can use the to_string method that chris mentioned (http://www.cplusplus.com/reference/string/to_string/?kw=to_string)
DrawScreenString(1,5, "Lives Remaining: " + std::to_string(livesRemaining), 0xF00000, NULL).
However, if your compiler doesn't have the to_string functionality, you can use a stringstream to construct (http://www.cplusplus.com/reference/sstream/stringstream/stringstream/) or sprintf into a char buffer and then constructing the string from a char buffer. I personally don't like the sprintf option because of the fixed buffer and concerns about overflow of the buffer if the input isn't checked, but it is an option.
Edit: Example with stringstream added per OP request:
#include <sstream>
...
std::stringstream ss;
int livesRemaining = 5;
ss << "Lives remaining: " << livesRemaining;
DrawScreenString(1,5, ss.str(), 0xF00000, NULL);
You can append your string "Lives: " to the livesRemaining variable like so:
"Lives : %d :"+Integer.toString(uicolor)
OR
"Lives : %d :"+uicolor + ""
OR
"Lives : %d :"+String.valueOf(uicolor)
Finally, looking like this for example:
DrawScreenString(10, 5,"Lives : %d :"+Integer.toString(uicolor), 0xF14040, NULL);
livesRemaining = 3

How to print string literal and QString with qDebug?

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 .

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.