Convert double point coordinates into string - c++

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.

Related

Overload << operator to change " " to "\n"

I am trying to overload
<<
operator. For instance
cout << a << " " << b << " "; // I am not allowed to change this line
is given I have to print it in format
<literal_valueof_a><"\n>
<literal_valueof_b><"\n">
<"\n">
I tried to overload << operator giving string as argument but it is not working. So I guess literal
" "
is not a string. If it is not then what is it. And how to overload it?
Kindly help;
Full code
//Begin Program
// Begin -> Non - Editable
#include <iostream>
#include <string>
using namespace std;
// End -> Non -Editable
//---------------------------------------------------------------------
// Begin -> Editable (I have written )
ostream& operator << (ostream& os, const string& str) {
string s = " ";
if(str == " ") {
os << '\n';
}
else {
for(int i = 0; i < str.length(); ++i)
os << str[i];
}
return os;
}
// End -> Editable
//--------------------------------------------------------------------------
// Begin -> No-Editable
int main() {
int a, b;
double s, t;
string mr, ms;
cin >> a >> b >> s >> t ;
cin >> mr >> ms ;
cout << a << " " << b << " " ;
cout << s << " " << t << " " ;
cout << mr << " " << ms ;
return 0;
}
// End -> Non-Editable
//End Program
Inputs and outputs
Input
30 20 5.6 2.3 hello world
Output
30
20
5.6
2.3
hello
world
" " is a string-literal of length one, and thus has type const char[2]. std::string is not related.
Theoretically, you could thus overload it as:
auto& operator<<(std::ostream& os, const char (&s)[2]) {
return os << (*s == ' ' && !s[1] ? +"\n" : +s);
}
While that trumps all the other overloads, now things get really hairy. The problem is that some_ostream << " " is likely not uncommon, even in templates, and now no longer resolves to calling the standard function. Those templates now have a different definition in the affected translation-units than in non-affected ones, thus violating the one-definition-rule.
What you should do, is not try to apply a global solution to a very local problem:
Preferably, modify your code currently streaming the space-character.
Alternatively, write your own stream-buffer which translates it as you wish, into newline.
Sure this is possible, as I have tested. It should be portable since you are specifying an override of a templated function operator<<() included from <iostream>. The " " string in your code is not a std::string, but rather a C-style string (i.e. a const char *). The following definition works correctly:
ostream& operator << (ostream& os, const char *str) {
if(strcmp(str, " ") == 0) {
os << '\n';
} else {
// Call the standard library implementation
operator<< < std::char_traits<char> > (os, str);
}
return os;
}
Note that the space after std::char_traits<char> is necessary only if you are pre-c++11.
Edit 1
I agree with Deduplicator that this is a potentially dangerous solution as it may cause undesirable consequences elsewhere in the code base. If it is needed only in the current file, you could make it a static function (by putting it within an unnamed namespace). Perhaps if you shared more about the specifics of your problem, we could come up with a cleaner solution for you.
You might want to go with a user defined literal, e.g.
struct NewLine {};
std::ostream& operator << (std::ostream& os, NewLine)
{
return os << "\n";
}
NewLine operator ""_nl(const char*, std::size_t) // "nl" for newline
{
return {};
}
This can be used as follows.
int main(int, char **)
{
std::cout << 42 << ""_nl << "43" << ""_nl;
return 0;
}
Note three things here:
You can pass any string literal followed by the literal identifier, ""_nl does the same thing as " "_nl or "hello, world"_nl. You can change this by adjusting the function returning the NewLine object.
This solution is more of an awkward and confusing hack. The only real use case I can imagine is pertaining the option to easily change the behavior at a later point in time.
When doing something non-standard, it's best to make that obvious and explicit - here, the user defined literal indeed shines, because << ""_nl is more likely to catch readers' attention than << " ".

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;

ostream method does not work

i have two methods the first one defined string:
I do not understand why it does not make it and how i call to this method from the main.
Actor::operator std::string( ) const {
std::stringstream ss;
ss << this->_id;
std::string str1 = ss.str();
std::stringstream s;
s << this->_salary;
std::string str2 = s.str();
std::string str3 = "Actor first name = " + this->_firstname + ", last name = " + this->_lastname+", id = " + str1 + ", monthly salary = " + str2;
if (this->_hasoscar==true)
str3+=" was NOMINATED Oscar AWARD..";
return str3;
}
the next one need to print it
const Actor& Actor::print(std::ostream& os) {
os<< std::string();
return *this;
}
Is not clear why your doing this because the normal way to work is overloading ostream operator:
class Actor {
public:
friend std::ostream& operator<< (std::ostream& os, const Actor& a) {
os << "Actor first name = " + a._firstname +
", last name = " + a._lastname+", id = " +
a._id + ", monthly salary = " + a._salary;
if (this->_hasoscar) {
os << " was NOMINATED Oscar AWARD..";
}
return os;
}
};
In this way, from main, you can create and print actor easily:
Actor a;
cout << a;
First method
Actor::operator std::string() const();
allow you implicit conversion from Actor to string, for example:
Person a;
std::string s = a;
os<< std::string();
This does not call the conversion to string, it creates a temporary string variable and writes it to the stream, so it is equivalent to:
os << "";
To call the conversion operator you need to tell the compiler you want to convert the object to a string (not just construct an empty string). The explicit way to do that is:
os << static_cast<std::string>(*this);
There are other ways such as:
os << std::string(*this);
os << (std::string)*this;
std::string s = *this;
os << s;
or if you like unreadable code you can call the conversion operator explicitly:
os << this->operator std::string();
(That last way is not a good idea.)
The definition of your conversion operator is very silly, and much slower than it needs to be. Using two separate stringstreams and also string concatenation is very wasteful, you can do it all with a single stringstream:
Actor::operator std::string( ) const {
std::stringstream ss;
ss << "Actor first name = " << this->_firstname
<< ", last name = " << this->_lastname
<< ", id = " << this->_id
<< ", monthly salary = " << this->_salary;
if (this->_hasoscar==true)
ss << " was NOMINATED Oscar AWARD..";
return ss.str();
}
However, as Velthune says, unless you need conversion to string for other reasons, the usual way to output your class would be to overload operator<< for the class.

Difficulty in ostream

ostream& operator<<(ostream& os, const PT& p)
{
os << "(" << p.x << "," << p.y << ")";
}
PT is a structure and x , y are its members.
Can someone please explain what exactly the above line does. Can't the desired text be printed using cout?
I came across this snippet of code from this site.
It's a custom overload for operator<<.
It means you can do this:
PT p = ...;
std::cout << p << "\n";
or this:
PT p = ...;
std::stringstream ss;
ss << p << "\n";
std::cout << ss;
or lots of other useful stuff.
However, it should be noted that the code you quoted won't work properly. It needs to return os.
This provides a method of outputting the PT. Now, you can use this:
PT p;
std::cout << p;
This gets translated into a call of
operator<< (std::cout, p);
That matches your overload, so it works, printing the x and y values in brackets with less effort on the user's part. In fact, it doesn't have to be cout. It can be anything that "is" a std::ostream. There are quite a few things that inherit from it, meaning they are std::ostreams as well, and so this works with them too. std::ofstream, for file I/O, is one example.
One thing that the sample you found doesn't do, but should, though, is return os;. Without doing that, you can't say std::cout << p << '\n'; because the result of printing p will not return cout for you to use to print the newline.
It allows the << operator to append the PT object to the stream. It seems the object has elements x and y that are added with a comma separator.
This operator << overloading for outputing object of PT class .
Here:
ostream& operator<<(ostream& os, const PT& p)
First param is for output stream where p will be appended.
It returns reference to os for chaining like this:
cout << pt << " it was pt" << endl;

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();