How to form a C++ string from concatenations of string literals? - c++

I would like concatenate string literals and ints, like this:
string message("That value should be between " + MIN_VALUE + " and " + MAX_VALUE);
But that gives me this error:
error: invalid operands of types ‘const char*’ and ‘const char [6]’ to binary ‘operator+’|
What is the correct way to do that? I could split that in 2 string declarations (each concatenating a string literal and a int), but that's ugly. I've also tried << operator.
Thanks

You should probably use stringstream for this.
#include <sstream>
std::stringstream s;
s << "This value shoud be between " << MIN_VALUE << " and " << MAX_VALUE;
message = s.str();

The c++ way to do this is to use a stringstream then you can use the << operator. It will give you a more consistent code feel

There are many ways to do this, but my favourite is:
string message(string("That value should be between ") + MIN_VALUE + " and " + MAX_VALUE);
That extra string() around the first literal makes all the difference in the world because there is an overloaded string::operator+(const char*) which returns a string, and operator+ has left-to-right associativity, so the whole thing is turned into a chain of operator+ calls.

#include <sstream>
#include <string>
template <typename T>
std::string Str( const T & t ) {
std::ostringstream os;
os << t;
return os.str();
}
std::string message = "That value should be between " + Str( MIN_VALUE )
+ " and " + Str( MAX_VALUE );

You probably want to use a stringstream like this:
std::stringstream msgstream;
msgstream << "That value should be between " << MIN_VALUE << " and " << MAX_VALUE;
std::string message(msgstream.c_str());

Related

Unable to concat strings in C++?

I have a method to log with the following definition:
void log(std::string s) {
std::string tag = "main";
std::cout << tag << " :" << s << std::endl;
}
I'm trying to call this method like this:
log("direction" << std::to_string(direction) << ", count: " << std::to_string(count));
direction and count are integers.
I'm getting this following error with << underlined in red:
no operator << matches these operands.
operand types are const char [10] << std::string
I have #include<string> in my header to make sure my strings are working as they should.
I tried std::string("direction") and still the issue was same.
Beginner in C++. Help would be appreciated.
operator<< isn't used for arbitrary string concatenation - it is called an "output stream operator", and it is only used in the context of std::ostream.
When you say...
std::cout << tag << " :" << s << std::endl;
...you're actually writing code roughly equivalent to:
std::cout.operator<<(tag).operator<<(" :").operator<<(s).operator<<(std::endl);
As you can see operator<< knows how to work with std::cout and std::string, but not between strings.
In order to concatenate std::string instances, you can simply use operator+:
log("direction" + std::to_string(direction) + ", count: " + std::to_string(count));
Please note that this concatenation technique is not the most efficient: you might want to look into std::stringstream or simply use std::string::reserve to avoid unnecessary memory allocations.
Substitute the << with the + operator as you are manipulating the string, not the stream:
log("direction" + std::to_string(direction) + ", count: " + std::to_string(count));
If you're determined to use the operator<< notation you need an object that understands it.
Here's such an object (I make no claims that this is a good idea):
#include <string>
#include <sstream>
#include <iostream>
void log(std::string s) {
std::string tag = "main";
std::cout << tag << " :" << s << std::endl;
}
struct string_accumulator
{
std::ostringstream ss;
template<class T>
friend string_accumulator& operator<<(string_accumulator& sa, T const& value)
{
sa.ss << value;
return sa;
}
template<class T>
friend string_accumulator& operator<<(string_accumulator&& sa, T const& value)
{
return operator<<(sa, value);
}
operator std::string () { return ss.str(); }
};
inline auto collect() -> string_accumulator
{
return string_accumulator();
}
int main()
{
int direction = 1;
int count = 1;
log(collect() << "direction" << std::to_string(direction) << ", count: " << std::to_string(count));
}
The prototype of your function is void log(std::string s);. It awaits for an std::string. So you need to pass a string to it, not a stream!
So, change this:
log("direction" << std::to_string(direction) << ", count: " << std::to_string(count));
to this:
log("direction" + std::to_string(direction) + ", count: " + std::to_string(count));
where I only changed the << operator to + operator. It will now concatenate everything inside the parentheses to a single std::string.
Your attempt implies that you wanted to pass std::ostream as the parameter. Maybe you want to read C++ Passing ostream as parameter. However, if I were you, I would just overload <<.
why don't you use:
// just include thisusing namespace std;

Convert doubles to char*/string in C++

I am pretty sure this is no hard task, but I don’t get what causes the problems, and I would like to really understand this, since I often have some pointer/array/cast-related problems:
I store the bounding box values in a double*
// this is the calss-variable
double *_boundingBox;
// this is where I put some data in it
double boundingBox[6];
boundingBox[0] =
.
.
.
boundingBox[6] = ....;
// set pointer to boundingbox
_boundingBox = &boundingBox;
and in an other class I use this
double* getBoundingBoxInfo()
{
return _boundingBox;
}
to get my bounding box-data, which I would like to input in a QLabel as QString
double boundingBox[6];
boundingBox[0] = *_drawer->getBoundingBoxInfo();
std::string stringX = "x start: " << boundingBox[0] << "\tx end: " << boundingBox[3];
QLabel *labelX = new QLabel(QString(stringX.c_str()));
The current compile-error is
error: invalid operands of types ‘const char [10]’ and ‘double’ to binary ‘operator<<’
Could someone please tell me how this should work? Am I using double*, double[] and string the way they are supposed to be used?
You cannot stream data into a std::string as-is. A solution is to use std::ostringstream:
std::ostringstream out;
out << "x start: " << boundingBox[0] << "\tx end: " << boundingBox[3];
std::string stringX = out.str();
The compilation error you're getting is for "x start: " << boundingBox[0].
The type of "x start: " is const char*, and the type of boundingBox[0] is double.
But there is no definition for operator<<(const char*,double).
You can get this to work by using an ostringstream object:
ostringstream oss;
oss << "x start: " << boundingBox[0] << "\tx end: " << boundingBox[3];
std::string stringX = oss.str();
As a side-note, when you set _boundingBox = &boundingBox, you don't need the &, because boundingBox is an array, so in essence, boundingBox == &boundingBox.
The reason for this (in case you were wondering) is that arrays don't have an l-value, and you cannot change the value of an array (for example, you cannot do boundingBox = ...).
QString provides everything http://qt-project.org/doc/qt-4.8/qstring.html#arg-20
so just use
QString("some text for double value: %1").arg(yourdouble, <additional parameters>)
and in your case:
... new QLabel(QString("x start: %1\tx end: %2").arg(boundingBox[0]).arg(boundingBox[3]));

Convert double point coordinates into string

string Point::ToString(const Point& pt)
{
std::stringstream buffX; //"Incomplete type is not allowed"????
buffX << pt.GetX(); // no operator "<<" matches these operands????
std::stringstream buffY;
buffY << pt.GetY();
string temp = "Point(" + buffX + ", " + buffY + ")"; //???....how to combine a couple of strings into one?..
return temp.str();
}
I followed the code from similar questions, but the system says "Incomplete type is not allowed"---red line under buffX
also red line under "<<" says that---- no operator "<<" matches these operands
really don't know why..
Thank you!
You need to #include <sstream> to use std::ostringstream.
Then:
std::string Point::ToString(const Point& pt)
{
std::ostringstream temp;
temp << "Point(" << pt.GetX() << ", " << pt.GetY() << ")";
return temp.str();
}
It's not clear why you're passing in a Point, since this is a member of that class. Perhaps cleaner would be:
std::string Point::ToString() const
{
std::ostringstream temp;
temp << "Point(" << GetX() << ", " << GetY() << ")";
return temp.str();
}
This, perhaps incorrectly, assumes that GetX() and GetY() return some kind of numeric type (int, float, double, ...). If this is not the case, you may want to either change them (the principle of least astonishment) or access the underlying data members of the class directly.
If you're struggling with this kind of compiler error, I strongly recommend you get yourself a good C++ book.

Concatenation operator in C++?

I have an application in which I need to combine strings within a variable like so:
int int_arr[4];
int_arr[1] = 123;
int_arr[2] = 456;
int_arr[3] = 789;
int_arr[4] = 10;
std::string _string = "Text " + int_arr[1] + " Text " + int_arr[2] + " Text " + int_arr[3] + " Text " + int_arr[4];
It gives me the compile error
Error C2210: '+' Operator cannot add pointers" on the second string of the expression.
As far as I can tell I am combining string literals and integers, not pointers.
Is there another concatenation operator that I should be using? Or is the expression just completely wrong and should figure out another way to implement this?
BTW I am using Visual Studio 2010
Neither C nor C++ allow concatenation of const char * and int. Even C++'s std::string, doesn't concatenate integers. Use streams instead:
std::stringstream ss;
ss << "Text " << int_arr[1] << " Text " << int_arr[2] << " Text " << int_arr[3] << " Text " << int_arr[4];
std::string _string = ss.str();
You can do this in Java since it uses the toString() method automatically on each part.
If you want to do it the same way in C++, you'll have to explicitly convert those integer to strings in order for this to work.
Something like:
#include <iostream>
#include <sstream>
std::string intToStr (int i) {
std::ostringstream s;
s << i;
return s.str();
}
int main (void) {
int var = 7;
std::string s = "Var is '" + intToStr(var) + "'";
std::cout << s << std::endl;
return 0;
}
Of course, you can just use:
std::ostringstream os;
os << "Var is '" << var << "'";
std::string s = os.str();
which is a lot easier.
A string literal becomes a pointer in this context. Not a std::string. (Well, to be pedantically correct, string literals are character arrays, but the name of an array has an implicit conversion to a pointer. One predefined form of the + operator takes a pointer left-argument and an integral right argument, which is the best match, so the implicit conversion takes place here. No user-defined conversion can ever take precedence over this built-in conversion, according to the C++ overloading rules.).
You should study a good C++ book, we have a list here on SO.
A string literal is an expression returning a pointer const char*.
std::stringstream _string_stream;
_string_stream << "Text " << int_arr[1] << " Text " << int_arr[2] << " Text " << int_arr[3] << " Text " << int_arr[4];
std::string _string = _string_stream.str();

Convert double to string C++? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How do I convert a double into a string in C++?
I want to combine a string and a double and g++ is throwing this error:
main.cpp: In function ‘int main()’:
main.cpp:40: error: invalid operands of types ‘const char [2]’ and ‘double’ to binary ‘operator+’
Here is the line of code which it is throwing the error on:
storedCorrect[count] = "("+c1+","+c2+")";
storedCorrect[] is a string array, and c1 and c2 are both doubles. Is there a way to convert c1 and c2 to strings to allow my program to compile correctly?
You can't do it directly. There are a number of ways to do it:
Use a std::stringstream:
std::ostringstream s;
s << "(" << c1 << ", " << c2 << ")";
storedCorrect[count] = s.str()
Use boost::lexical_cast:
storedCorrect[count] = "(" + boost::lexical_cast<std::string>(c1) + ", " + boost::lexical_cast<std::string>(c2) + ")";
Use std::snprintf:
char buffer[256]; // make sure this is big enough!!!
snprintf(buffer, sizeof(buffer), "(%g, %g)", c1, c2);
storedCorrect[count] = buffer;
There are a number of other ways, using various double-to-string conversion functions, but these are the main ways you'll see it done.
In C++11, use std::to_string if you can accept the default format (%f).
storedCorrect[count]= "(" + std::to_string(c1) + ", " + std::to_string(c2) + ")";
Use std::stringstream. Its operator << is overloaded for all built-in types.
#include <sstream>
std::stringstream s;
s << "(" << c1 << "," << c2 << ")";
storedCorrect[count] = s.str();
This works like you'd expect - the same way you print to the screen with std::cout. You're simply "printing" to a string instead. The internals of operator << take care of making sure there's enough space and doing any necessary conversions (e.g., double to string).
Also, if you have the Boost library available, you might consider looking into lexical_cast. The syntax looks much like the normal C++-style casts:
#include <string>
#include <boost/lexical_cast.hpp>
using namespace boost;
storedCorrect[count] = "(" + lexical_cast<std::string>(c1) +
"," + lexical_cast<std::string>(c2) + ")";
Under the hood, boost::lexical_cast is basically doing the same thing we did with std::stringstream. A key advantage to using the Boost library is you can go the other way (e.g., string to double) just as easily. No more messing with atof() or strtod() and raw C-style strings.
std::string stringify(double x)
{
std::ostringstream o;
if (!(o << x))
throw BadConversion("stringify(double)");
return o.str();
}
C++ FAQ:
http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.1
I believe the sprintf is the right function for you. I's in the standard library, like printf. Follow the link below for more information:
http://www.cplusplus.com/reference/clibrary/cstdio/sprintf/