C++ ostringstream strange behavior when chaining in cout is used - c++

I am a C++ beginner ( came from Java ). I have the following code:
//#include <boost/algorithm/string.hpp>
#include <iostream>
#include <math.h>
#include <vector>
#include <string.h>
#include <string>
#include <bitset>
#include <algorithm>
#include <sstream>
#include <memory>
#include <assert.h>
#include <cctype>
using namespace std;
class Point{
private:
int x;
int y;
public:
Point(int x,int y){
this->x=x;
this->y=y;
}
int getX(){
return x;
}
int getY(){
return y;
}
operator const char*(){
return toString().c_str();
}
string toString(){
ostringstream stream;
stream<<"( "<<x<<", "<<y<<" )";
return stream.str();
}
};
class Line{
private:
Point p1=Point(0,0);
Point p2=Point(0,0);
public:
Line(Point p1, Point p2){
this->p1=p1;
this->p2=p2;
}
Point getP1(){
return p1;
}
Point getP2(){
return p2;
}
operator const char*(){
ostringstream stream;
stream<<"[ "<<p1<<" -> "<<p2<<" ]";
return stream.str().c_str();
}
// operator const char*(){
// ostringstream stream;
// stream<<"[ "<<p1<<" -> ";
// stream<<p2<<" ]";
// return stream.str().c_str();
// }
};
int main()
{
Line line=Line(Point(1,2), Point(3,4));
cout<<line<<endl;
cout<<"\nProgram exited successfully."<<endl;
return 0;
}
I have redefined the operator const* so that I can use cout<
But, If I run the program as it is now, with the second block commented out ( I have 2 versions of operator const*, and by default the second one is commented out ) ,it will display
[ (1, 2) -> (1, 2) ]
But when running with the second block uncommented, the output is as expected:
[ (1, 2) -> (3, 4) ]
The issue seems to occur when I display both Point objects in the same line ( some kind of chaining, though I don't know if chaining is the right word here )
My question, is,why is this happening?
UPDATE
I have added the std::ostream& operator << function to my Line class but now I'm receiving the following errors:
/home/ryu/qt_workspace/hello/main.cpp:67: error: 'std::ostream& Line::operator<<(std::ostream&, const Line&)' must take exactly one argument
/home/ryu/qt_workspace/hello/main.cpp:77: error: cannot bind 'std::ostream {aka std::basic_ostream<char>}' lvalue to 'std::basic_ostream<char>&&'
Regards,
Aurelian

If you want to use cout <<, there is a more direct way to do that.
Add this function to Line.
friend std::ostream& operator << ( std::ostream & os, const Line & l ){
os << "[ " << l.p1 << " -> " << l.p2 << " ]";
return os;
}
You should also note that your approach was returning invalid memory - this is a significant way that Java differs from C++.
return stream.str().c_str(); // Danger!
stream was declared in operator const char*() which limits its lifetime to that function. It is destroyed when that scope is exited. As a result, you are returning a pointer to something that no longer exists.

actually I think with C++11 returning the string by value is perfectly fine, so you can do the transfer there instead of using the cstring underneath.
What are move semantics?

Related

Trying to convert a string into a int using stringstream

I'm trying check if a string representation equals given integer. I'm meant to use stringstream for this in a function. I also have an operator= for this as well.
I'm a little confused on how to execute these together and if I'm missing something. This is the last bit to an assignment I have, this is just a small snippet of my whole program. I can't find many guides on this, and I sense they all direct me to atoi or atod, which I'm not allowed to use.
#ifndef INTEGER
#define INTEGER
using std::string;
class Integer
{
private:
int intOne;
string strOne;
public:
Integer() {
intOne = 0;
}
Integer(int y) {
intOne = y;
}
Integer(string x) {
strOne = x;
}
void equals(string a);
Integer &operator=(const string*);
string toString();
};
#endif
In this header I'm not sure what argument I'm to use for the = operator.
#include <iostream>
#include <sstream>
#include <string>
#include "Integer.h"
using namespace std;
Integer &Integer::operator=(const string*)
{
this->equals(strOne);
return *this;
}
void Integer::equals(string a)
{
strOne = a;
toString(strOne);
}
string Integer::toString()
{
stringstream ss;
ss << intOne;
return ss.str();
}
#include <iostream>
#include <cstdlib>
#include <conio.h>
#include <string>
#include <ostream>
using namespace std;
#include "Menu.h"
#include "Integer.h"
#include "Double.h"
int main()
{
Integer i1;
i1.equals("33");
cout << i1;
}
Sorry if its a bad question I'm not too familiar with this type of assignment and will take any help I can get. Thanks.
you can use std::to_strig() that lets you convert from int to a string that represents the same number.
So if i understand correctly, you want to overload operator =, and that is a bad idea, since operator= is used for assignment not for comparison.
The correct operator signature is:
ReturnType operator==(const TypeOne first, const TypeSecond second) [const] // if outside of class
ReturnType operator==(const TypeSecond second) [const] // if inside class
Since you can't compare string to integer (they are different types), you need to write your comparisment function, since you don't have one i will write one for you:
bool is_int_equal_string(std::string str, int i)
{
std::string tmp;
tmp << i;
return tmp.str() == i;
}
Last but not least, you need to merge both of those, into one convenient operator:
// inside your Integer class
bool operator==(std::string value) const
{
std::stringstream tmp;
tmp << intOne;
return tmp.str() == ref;
}
Now you can use this operator, just like any other:
Integer foo = 31;
if (foo == "31")
cout << "Is equal" << endl;
else
cout << "Is NOT equal" << endl;
I hope this helps.
If you are allowed to use std::to_string then it would be the best.
Otherwise, you could create a function to handle the equality between the string and the integer with the use of std::stringstream:
Example:
bool Integer::equal(const string& str)
{
stringstream ss(str);
int str_to_int = 0;
ss >> str_to_int;
if (intOne == str_to_int)
return true;
else
return false;
}
Combine this with an if statement:
int main()
{
Integer i{100};
if (i.equal("100"))
cout << "true" << endl;
else
cout << "false" << endl;
}

C++ output operator overloading

I wanted to try to overload "<<" operator for an output stream and a custom class Article.
my.h
#include <iostream>
using namespace std;
class Article {
string body;
string header;
string author;
public:
Article();
void addHeader(const string&);
void addBody(const string&);
string getHeader();
string getBody();
};
my.cpp
string Article::getHeader() {
return header;
}
void Article::addBody(const string& body) {
this->body = body;
}
void Article::addHeader(const string& header) {
this->header = header;
}
ostream& operator<<(ostream& os, Article& article) {
return os << article.getHeader() << "\n\n" << article.getBody();
}
main.cpp
#include <iostream>
#include <string>
#include "my.h"
void main() {
char bye;
Article article = Article();
article.addBody("This is my article! thank you!");
article.addHeader("Header");
cout << article.getHeader() << "\n";
cout << article.getBody() << "\n";
cout << article;
cin >> bye;
}
This code doesn't compile. VS 2013 says:
binary '<<' : no operator found which takes a right-hand operand of type 'Article' (or there is no acceptable conversion)
If I remove the last line, it compiles successfully and the output of getHeader() and getBody() is as expected. They both return strings so it should be a piece of cake.
This problem seems very simple, however, as simple as it is I can't figure out what is happenning.
Now that you have posted real code the answer is obvious.
You define your operator << in my.cpp, but you don't declare it in my.h, so when compiling main.cpp the compiler has no way of knowing it exists.
Add a declaration of the function to your header.

C++ error: output not defined in namespace

Update: I made Sergii's changes below, but now I get the error: undefined reference to `cs202::operator<<(std::basic_ostream >&, cs202::Rational const&)'. Any ideas how to fix this? Thanks
I would appreciate help figuring out why I am getting this error:
"error: 'output' is not a member of namespace 'cs202'"
I have a class called Rational as follows:
#ifndef RATIONAL_H
#define RATIONAL_H
namespace cs202{
class Rational
{
private:
int m_numerator;
int m_denominator;
public:
Rational(int nNumerator = 0, int nDenominator = 1) {
m_numerator = nNumerator;
m_denominator = nDenominator;
}
int getNumerator(){return m_numerator;}
int getDenominator(){return m_denominator;}
friend std::ostream& operator<<(std::ostream& output, const Rational& cRational);
};
}
#endif
The implementation file for the friend function which overrides the << operator looks like this:
#include "rational.h"
namespace cs202{
friend std::ostream& operator<<(std::ostream& output, const Rational& cRational)
{
output << cRational.m_numerator << "/" << cRational.m_denominator;
return output;
}
}
Finally, Main looks like this:
#include <iostream>
#include "rational.h"
using namespace std;
using namespace cs202;
int main()
{
Rational fraction1(1, 4);
cs202::output << fraction1 << endl;
return 0;
}
I have tried using cout instead of cs202:output, I have tried with and without the namespace cs202 (which is a requirement of the assignment), and I have tried making the operator overload function a member function of the class rather than a friend function to no avail.
What am I missing? Thanks
I suppose you want it out to standard output (to console)
int main()
{
Rational fraction1(1, 4);
std::cout << fraction1 << endl;
return 0;
}
Also you do not need friend here. "Friend" keyword is used only in a class
#include "rational.h"
namespace cs202{
std::ostream& operator<<(std::ostream& output, const Rational& cRational)
{
output << cRational.m_numerator << "/" << cRational.m_denominator;
return output;
}
}
Thanks, I figured it out. I had to change the placement of the {} for the namespace.

Overloaded operator << outputs bool value. why?

xml_attribute.h
#pragma once
#ifndef XML_ATTRIBUTET_H
#define XML_ATTRIBUTET_H
#include <string>
#include <iostream>
struct XML_AttributeT{
std::string tag;
std::string value;
//constructors
explicit XML_AttributeT(std::string const& tag, std::string const& value);
explicit XML_AttributeT(void);
//overloaded extraction operator
friend std::ostream& operator << (std::ostream &out, XML_AttributeT const& attribute);
};
#endif
xml_attribute.cpp
#include "xml_attribute.h"
//Constructors
XML_AttributeT::XML_AttributeT(std::string const& tag_, std::string const& value_)
: tag{tag_}
, value{value_}
{}
XML_AttributeT::XML_AttributeT(void){}
//overloaded extraction operator
std::ostream& operator << (std::ostream &out, XML_AttributeT const attribute){
return out << attribute.tag << "=" << attribute.value;
}
driver.cpp
#include <iostream>
#include <cstdlib>
#include "xml_attribute.h"
int main(){
using namespace std;
XML_AttributeT a();
cout << a << endl;
return EXIT_SUCCESS;
}
The output from the driver is a '1' but I want it to be an '=' sign.
Why is it outputting the reference to a?
If I change XML_AttributeT a(); to XML_AttributeT a; it doesn't even compile.
What did I do wrong?
chris is correct. Your initial issue is that XML_AttributeT a() is interpreted as a function declaration. clang++ will actually warn you of this:
Untitled.cpp:33:21: warning: empty parentheses interpreted as a function declaration [-Wvexing-parse]
XML_AttributeT a();
You can use a{} instead to fix this.
At this point you get a new error:
Untitled.cpp:34:10: error: use of overloaded operator '<<' is ambiguous (with operand types 'ostream' (aka 'basic_ostream<char>') and 'XML_AttributeT')
cout << a << endl;
This is because of what jogojapan said. Your implemented operator<< is using XML_AttributeT const as the attribute type instead of XML_AttributeT const &. If you fix that, then it compiles and gives you the result you want.

Overload on << like cout error

I'm trying to create a class like std::cout, however, with colored output. The idea is to call colorstream, but when I overload the operator << gives error.
Codes below:
main.cpp
#include <colorstream/colorstream.hpp>
int main ( int argc, char **argv )
{
cpk::colorstream test;
test << "Hello World";
return 0;
}
colorstream/colorstream.hpp
#include <string>
#ifndef CPK_COLORSTREAM_HPP
#define CPK_COLORSTREAM_HPP
namespace cpk
{
class colorstream
{
public:
colorstream ( ) { };
colorstream operator<<( std::string n );
};
}
#endif // #ifndef CPK_COLORSTREAM_HPP
colorstream/colorstream.cpp
#include <string>
#include <iostream>
/**
* CPK Color Stream Header
*/
#include <colorstream/colorstream.hpp>
cpk::colorstream::colorstream operator<<( std::string n )
{
std::cout << n << std::endl;
}
This is the first time I'm trying to overload operators in, so please help me and if I can explain my mistake.
Thank you, Bruno Alano
#edit
The error:
CMakeFiles/cpk.dir/source/cpk.cpp.o: In function `main':
cpk.cpp:(.text+0x45): undefined reference to `cpk::colorstream::operator<<(std::basic_string<char, std::char_traits<char>, std::allocator<char> >)'
collect2: ld returned 1 exit status
make[2]: ** [cpk] Erro 1
make[1]: ** [CMakeFiles/cpk.dir/all] Erro 2
make: ** [all] Erro 2
Well, the error is that you're definition of the operator is garbled. It should be
cpk::colorstream cpk::colorstream::operator<< (std::string n)
That said, I strong recommend not to pursue this approach further! To create custom streams you want to derive from std::streambuf and override the relevant operations there (e.g. overflow() and, possibly, xsputn() for output streams).
Actually, if you want to change color e.g. using ANSI Escape Codes you can just create suitable color manipulators and use them with an std::ostream:
#include <iostream>
namespace color
{
std::ostream& red(std::ostream& out) {
return out << "\x1b[31m";
}
std::ostream& reset(std::ostream& out) {
return out << "\x1b[0m";
}
}
int main()
{
std::cout << "hello " << color::red << "world" << color::reset << "\n";
}
On non-UNIX platforms some other mechanism might be necessary, though...
When defining a member operator, what you need to qualify with the class name is the operator name, not the return type.
namespace cpk {
colorstream colorstream::operator<<( std::string n )
{
std::cout << n << std::endl;
}
}
Now, to allow chaining calls to << like you can do with std::cout you need to actually return a value from your operator!
namespace cpk {
colorstream colorstream::operator<<( std::string n )
{
std::cout << n << std::endl;
return *this;
}
}
However, this will return a copy of the stream because it returns by value. That's probably not desirable, so you might be better with returning by reference:
colorstream& colorstream::operator<<( std::string n )
{
std::cout << n << std::endl;
return *this;
}
I need more information on what you are trying to accomplish and what are the errors that are coming up.
I made an assumption with the code provided below that you wanted to output the color to standard out.
I feel that I am completely wrong with this assumption, however here is the code...
main.cpp
#include <colorstream/colorstream.hpp>
int main ( int argc, char **argv )
{
cpk::colorstream test;
test.SetColor("RED");
std::cout << test << std::endl;
return 0;
}
colorstream/colorstream.hpp should be:
#include <iostream>
#include <string>
#ifndef CPK_COLORSTREAM_HPP
#define CPK_COLORSTREAM_HPP
namespace cpk
{
class colorstream
{
public:
std::ostream& operator<< (std::ostream& stream, const cpk::colorstream& cs);
void SetColor(const std::string &color){m_Color = color;}
private:
std::string m_Color;
};
}
#endif // #ifndef CPK_COLORSTREAM_HPP
colorstream/colorstream.cpp should be:
#include <string>
#include <iostream>
/**
* CPK Color Stream Header
*/
#include <colorstream/colorstream.hpp>
std::ostream& operator<<(std::ostream& stream, const cpk::colorstream& cs)
{
stream << cs.m_Color;
return stream;
}