Stream object directly into a std::string - c++

Given some type that is streamable:
struct X {
int i;
friend std::ostream& operator<<(std::ostream& os, X const& x) {
return os << "X(" << x.i << ')';
}
};
I want to append this onto a std::string. I can implement this as:
void append(std::string& s, X const& x) {
std::ostringstream os;
os << x;
s.append(os.str());
}
But this seems lame since I'm writing data into one stream just to then allocate a new string just for the purposes of appending it onto a different one. Is there a more direct route?

This can be solved by a new type of streambuf (see Standard C++ IOStreams and Locales: Advanced Programmer's Guide and Reference).
Here is a sketch of how it can look:
#include <streambuf>
class existing_string_buf : public std::streambuf
{
public:
// Store a pointer to to_append.
explicit existing_string_buf(std::string &to_append);
virtual int_type overflow (int_type c) {
// Push here to the string to_append.
}
};
Once you flesh out the details here, you could use it as follows:
#include <iostream>
std::string s;
// Create a streambuf of the string s
existing_string_buf b(s);
// Create an ostream with the streambuf
std::ostream o(&b);
Now you just write to o, and the result should appear as appended to s.
// This will append to s
o << 22;
Edit
As #rustyx correctly notes, overriding xsputn is required for improving performance.
Full Example
The following prints 22:
#include <streambuf>
#include <string>
#include <ostream>
#include <iostream>
class existing_string_buf : public std::streambuf
{
public:
// Somehow store a pointer to to_append.
explicit existing_string_buf(std::string &to_append) :
m_to_append(&to_append){}
virtual int_type overflow (int_type c) {
if (c != EOF) {
m_to_append->push_back(c);
}
return c;
}
virtual std::streamsize xsputn (const char* s, std::streamsize n) {
m_to_append->insert(m_to_append->end(), s, s + n);
return n;
}
private:
std::string *m_to_append;
};
int main()
{
std::string s;
existing_string_buf b(s);
std::ostream o(&b);
o << 22;
std::cout << s << std::endl;
}

You could write a std::string casting operator:
struct X {
int i;
friend std::ostream& operator<<(std::ostream& os, X const& x) {
os << "X(" << x.i << ')';
return os;
}
operator std::string() {
return std::string("X(") + std::to_string(x.i) + ")";
}
};
Then, you could simply append it to a std::string:
X myX;
myX.i = 2;
std::string s("The value is ");
s.append(myX); //myX is cast into the string "X(2)"

In this specific case I'd just follow the KISS principle:
struct X {
int i;
std::string toString() const {
return "X(" + std::to_string(i) + ")";
}
};
Usage:
string += x.toString();
std::cout << x.toString();
An operator<<(std::ostream&, …) isn't really suitable for generic string conversion, so if that's what you're after then a toString type of method / free function is much better. And if you want std::cout << x you can trivially implement operator<< to just call toString.

Since the original string is likely only large enough for the existing allocation, the best you can hope for is to format everything you want to append once in the stream, then append the result as you have in your example.
If you plan on performing these appends often, I would argue std::string is the wrong type for the problem at hand. I would recommend using an std::ostringtream directly instead of a std::string, and only convert to a string when you need the final result.

Related

How can I static cast the output of the >> operator in c++?

Or perform any function really.
Currently I have some code that looks a bit like this:
int temp_int;
streamer >> temp_int;
finalObj = static_cast<CustomType>(temp_int);
ints can be cast into CustomTypes (obviously) and finalObj is of type CustomType
streamer's >> operator has not been set up to work with CustomType. Changing this is outside my area of control.
Im looking for a way to put the above code in a single line and avoid using a temporary variable.
When putting custom types back into the streamer, I use this:
streamer << static_cast<int>(someObj);
Thats a lot neater. And it would be great to have the instreaming and outstreaming look symmetrical for easier reading.
Thanks
Just implement an operator>> and make sure name lookup finds it.
struct CustomType
{
int m_value;
CustomType(int v = 0)
: m_value(v)
{}
operator int() const
{
return m_value;
}
};
namespace
{
std::istream& operator>>(std::istream& s, CustomType& out)
{
int temp;
s >> temp;
out = temp;
return s;
}
}
int main()
{
CustomType finalObj;
std::cin >> finalObj;
std::cout << finalObj << '\n';
}
Alternatively, if you aren't sure, if operator>> has already been implemented somewhere in an undesired manner, you could create a wrapper type and implement operator>> for it.
namespace
{
class CustomTypeParsingWrapper
{
public:
CustomTypeParsingWrapper(CustomType& target)
: m_target(target)
{
}
friend std::istream& operator>>(std::istream& s, CustomTypeParsingWrapper const& wrapper)
{
int temp;
s >> temp;
wrapper.m_target = temp;
return s;
}
private:
CustomType& m_target;
};
}
int main()
{
CustomType finalObj;
std::cin >> CustomTypeParsingWrapper(finalObj);
std::cout << finalObj << '\n';
}
Note: The use of the anonymous namespace here is only to avoid conflicts with implementations provided to other translation units. If you want to reuse operator>>, you should put it in the same namespace as CustomType to allow Argument Dependent Lookup to find it. A customTypeParsingWrapper intended to be reused could be put in a namespace of your choice...
One way to achieve what you want is to overload not only << and >> operators, but also the cast operator.
One way to do that is to overload the int() operator for CustomType. This way, you can use put your value back into the streamer easily:
class CustomType
{
private:
int _value;
public:
CustomType(const int &value) : _value(value) {}
// ...
operator int() const { return _value; }
};
This way, the compiler will find the appropriate cast from CustomType to int when using the << operator:
streamer << someObj;
will implicitly cast to int.
Similar overloads could be implemented to achieve the results.
Here is a full snipped to test this:
#include <iostream>
class CustomType
{
private:
int _value;
public:
CustomType(const int &value) : _value(value) {}
// ...
operator int() const { return _value; }
};
int main() {
auto someObj = CustomType(10);
std::cout << someObj;
}
This prints 10 to the standard output.

Overloading the ostream operator for a class wrapping stringstream

I'm currently writing a class to wrap stringstream. My overall goal is to provide a threadsafe << (ostream) for my stringstream. I'm having trouble figuring out the correct syntax of what I'm trying to do. Any help would be most appreciative!
Below you'll find what I've tried. I know this is not the correct syntax, but it is kind of what I'm shooting for. I could of course not overload the << operator and force users to use the AddValue, but that wouldn't be ideal for quick and easy string manipulation while writing the code.
class WrappedStringStream
{
public :
WrappedStringStream() ;
template<typename T>
void AddValue( const T & value )
{
m_mutex.Lock() ;
//here I'd like to do something like m_stringstream << value, but of course since
//I'm overloading operator<< that won't work
m_mutex.Unlock() ;
}
friend std::ostream & operator<<( std::ostream & out, const WrappedStringStream & string )
{
string.AddValue( out ) ;
return out ;
}
protected :
std::stringstream m_stringstream ;
mutable Mutex m_mutex ;
}
As mentioned above it doesn't compile, which I understand since I'm passing WrappedStringStream as a const parameter and calling AddValue which isn't const - resulting in the discards qualifier error.
Here is the solution
#include <iostream>
#include <sstream>
#include <mutex>
using namespace std;
class MutexWrapper
{
private:
mutex& m_mutex;
public:
MutexWrapper(mutex& mtx) : m_mutex(mtx) { mtx.lock () ; };
~MutexWrapper() { m_mutex.unlock () ; };
};
class WrappedStringStream
{
public :
WrappedStringStream() { };
template<typename T>
std::ostream & operator<<(const T& value)
{
MutexWrapper wrapper(m_mutex);
return m_stringstream << value;
}
void showStream()
{
cout << m_stringstream.str();
}
protected :
stringstream m_stringstream;
mutable mutex m_mutex ;
};
int main()
{
WrappedStringStream ws;
ws << "This is a string, " << 5 << 6.78;
ws.showStream();
return 0;
}
Output
This is a string, 56.78
======== edit ==========
Originally I was not quiet understand what the questioner's final goal, but just focus on how to fix his syntax issue.It is not a good idea to use << in a multithreading environment. We have a Log class, and in our log class we only have a Log method which takes variable amount of parameters. That will solve the problem.
Still, there is a solution for using << to lock the thread, but really urgly and NOT recommend. Downside is obvious - if you forgot to add the 'LoggingStart' and 'LoggingEnd', you might caught deadlock.
Also thanks #RemyLebeau, It should return *this instead of m_stringstream.
Please see code below.
#include <iostream>
#include <sstream>
#include <mutex>
using namespace std;
class WrappedStringStream
{
public:
enum StreamSignals
{
LoggingStart,
LoggingEnd
};
WrappedStringStream() { };
std::ostream & operator<<(const StreamSignals& signal)
{
if (signal == LoggingStart)
m_mutex.lock();
else if (signal == LoggingEnd)
m_mutex.unlock();
return *this;
}
template<typename T>
std::ostream & operator<<(const T& value)
{
m_stringstream << value;
return *this;
}
void showStream()
{
cout << m_stringstream.str();
}
protected :
stringstream m_stringstream;
mutable mutex m_mutex ;
};
int main()
{
WrappedStringStream ws;
ws << WrappedStringStream::StreamSignals::LoggingStart;
ws << "This is a string, " << 5 << 6.78;
ws << WrappedStringStream::StreamSignals::LoggingEnd;
ws.showStream();
return 0;
}

C++ Wrap cin and cout in class - Overload << and >> operators

I am trying to make a Console class. I would like to wrap cin and cout in the class and overload the << and >> operators. So I could use the class as such:
// Output
Console << "Call cout from Console" << endl;
// Input
string str;
Console >> str; // Call cin
My best guess was:
class Console {
//...
public:
ostream& operator<< (ostream& os)
{
cout << os;
return &cout;
}
//...
};
But I know that's wrong, how could I overload the operators to use the Console class as both cin and cout?
I got a working code that can handle the stream manipulators. You can see my code in action in this Ideone page
Here is the code:
#include <iostream>
typedef std::ostream& (*manip) (std::ostream&);
class console {
};
template <class T> console& operator<< (console& con, const T& x) { std::cout << x; return con; }
template <class T> console& operator>>(console& con, T& x) { std::cin >>x; return con; }
console& operator<< (console& con, manip manipulator){ std::cout<<manipulator; return con;}
int main() {
console c;
int a,b;
c>>a>>b;
c << "hello world"<<std::endl<<std::hex<<(a+b)<<std::endl;
}
Thanks #MooingDuck for the discussion that led me to a working answer and #111111 for the start point.
I don't know why would want to do such a thing but it isn't the stream you need to capture but the other type. But if this is just to make std::cout and std::cin more convenient I wouldn't bother.
class console {
};
template<typename T>
console& operator<<(console con, const T& val) {
std::cout << val;
return con;
}
console c;
c << "hello world\n";
This is not direct answer to your question, but maybe I point you out some alternative.
See my answer to some other question. To define yourself all of these <<and >> operators is not very easy. However you can overwrite streambuf for Console. Use combined streambufs of cin and cout,
Derive your console from std::iostream and your streambuf from std::streambuf
class console_streambuf : public std::streambuf {
public:
console_streambuf() {
// no buffering, overflow on every char
setp(0, 0);
}
virtual int_type overflow(int_type c) {
std::cout << c;
return c;
}
...
};
class console : public std::iostream {
public:
console() { rdbuf(&buf); }
private:
console_streambuf buf;
};
Contrary to many of the answers above, doing what you want is pretty simple, using the magic of templates.
I'd recommend using a stringstream, because using an ostream (cout is an ostream) can require arcane black magic (no joke).
#include <string>
#include <iostream>
#include <sstream>
struct console {
std::stringstream data_;
console() : data_() { };
// We make ourselves a template sink so we can "take" operator<<'s.
// The awesome advantage to using a template like this is that the
// compiler will allow us to "take" any data that can be converted
// to a stringstream, which will handle converting int's etc.
// for us!
template<typename T>
console& operator<<(const T& what) {
data_ << what;
return *this; // We must return a reference if we want to
// string together more than one thing, i.e.
// b << " " << 4;
}
void flush() {
std::cout << data_.str();
data_.clear();
std::cout.flush();
}
};
int main()
{
int a = 4;
console b;
console c;
b.data_ << 2;
c.data_ << 4;
//b << std::cout; // WHAT? it's possible but stupid, prints garbage
// Because we made the template return a reference, this will
// allow us to chain things just like we do with cout.
b << " HELLO WORLD! " << "yo!" << 4;
b << a << " " << 4.2f;
// Compiler chokes on this. It will try to convert "console"
// to a stringstream which it can't.
//b << c;
b.flush(); // Send out the output
// Wait for key press
char foo[500];
gets(foo);
}
Output:
2 HELLO WORLD! yo!44 4.2
Just like cout, except of course with more control.
You can get into using basic_ostream's and basic_istreams if you want binary I/O, but I'd recommend against it unless you really really need it.
Overloaded operator functions must be declared with the specific types you're going to call them with on the left and right. So you will need an operator<< (int), operator<< (double), operator<< (const std::string &), etc.
If you're really just going to pass them on to cin and cout, you can save typing by using a template member function, like:
template <class T> Console& operator<< (const T& x) { cout << x; return *this; }
[thanks to André for pointing out it should return Console& so you can string together calls like Console << a << b; ]

C++ streams operator << and manipulators / formatters

First, most of my recent work was Java. So even though I "know" C++, I do not want to write Java in C++.
And C++ templates are one thing I will really miss when going back to Java.
Now that this out of the way, if I want to do create a new stream formatter, say pic, that will have a single std::string parameter in it's constructor.
I would like the user to be able to write something like:
cout << pic("Date is 20../../..") << "100317" << endl;
The output should be
Date is 2010/03/17
How do I write the pic class? when the compiler sees the cout what are the underlying steps the compiler does?
Edit
Would it be more C++ to change that code into:
cout << pic("Date is 20../../..", "100317") << endl;
And possibly be easier to write the pic function as a standalone function (possibly template)?
It sounds like you are trying to write an alternate form of printf(). I'm not sure that this is a good idea, but if you decide to do it, you should definitely write it as a free function, because the manipulator issues (which have nothing to do with formatting using a format string) go away. I would also avoid templates to start with, and simply design and write the string version:
void pic( ostream & os, const string & fmt, const string & val );
Before writing such a function, you will have to be very clear in your mind what its semantics are, which I don't believe you are yet.
you might have a look at boost::format library.
somethings like this should work (if you can afford spliting your string first)
#include <iostream>
#include <string>
#include <boost/format.hpp>
int main()
{
const char* a = "102030";
std::string year(a, a + 2);
std::string month(a + 2, a +4);
std::string day(a + 4);
std::cout << boost::format("Date is 20%1%/%2%/%3%")% year % month % day << std::endl;
}
There are 2 questions here.
One deals with stream manipulators, follow the quote.
The other one deals with formatting issues.
Formatting is hard, especially the way you indicate it, because it involves being able to parse the format and generate an AST representation that will then be called to actually format the string. Parsing means that you need to define a small grammar etc...
There are libraries like Boost.Spirit who deals with parsing / generating, and they are much more complicated than the 'simple' Boost.Format (which itself is not that simple).
Now, could you forgo parsing ?
class Date
{
public:
Date(year_t year, month_t month, day_t day);
year_t getYear() const;
month_t getMonth() const;
day_t getDay() const;
private:
year_t mYear;
month_t mMonth;
day_t mDay;
};
The advantage of this class are multiple:
Structured information: parses one, reads as much as you wish
Validation: root out invalid date (29 Feb 2010 ?)
No ambiguity: is "100102" actually the "1st Feb 2010" or "2nd Jan 2010" ? (at least not once it's parsed)
Then, you can do the same for the format, by creating a little formatting engine.
template <class T>
class Formatter
{
public:
virtual ~Formatter() {}
virtual Formatter* clone() const = 0;
virtual std::string evaluate(const T& item) const = 0;
};
template <class T>
class FormatterConstant: public Formatter
{
public:
explicit FormatterConstant(const std::string& s): mValue(s) {}
virtual Formatter<T>* clone() const { return new FormatterConstant(*this); }
virtual std::string evaluate(const T&) const { return mValue; }
private:
std::string mValue;
};
template <class T>
class FormatterComposite: public Formatter<T>
{
typedef std::vector< const Formatter<T>* > formatters_type;
typedef typename formatters_type::const_iterator const_iterator;
public:
// Need suitable Copy and Assignment Constructors
~FormatterComposite()
{
for(const_iterator it = mFormatters.begin(), end = mFormatters.end();
it != end; ++it) delete *it;
}
virtual Formatter<T>* clone() const { return new FormatterComposite(*this); }
virtual std::string evaluate(const T& item) const
{
std::string result;
for(const_iterator it = mFormatters.begin(), end = mFormatters.end();
it != end; ++it) result += (*it)->evaluate();
return result;
}
void imbue(std::ostream& s) { mStream = &s; }
FormatterComposite& operator<<(const std::string& s)
{
mFormatters.push_back(new FormatterConstant<T>(s); }
return *this;
}
FormatterComposite& operator<<(const Formatter<T>& formatter)
{
mFormatters.push_back(formatter.clone());
return *this;
}
std::ostream& operator<<(const T& item) const
{
return (*mStream) << this->evaluate(item);
}
private:
std::ostream* mStream;
formatters_type mFormatters;
};
template <class T>
FormatterComposite& operator<<(std::ostream& s, FormatterComposite& c)
{
c.imbue(s);
return c;
}
// Usage
class DateOfYear: public Formatter<Date>
{
public:
Formatter<Date>* clone() const { return new DateOfYear(*this); }
std::string evaluate(const Date& d) const { return toString(d.getYear()); }
};
extern const DateOfYear year;
int main(int argc, char* argv[])
{
FormatterComposite<Date> formatter;
Date date;
std::cout << formatter << "Date is 20"
<< year << "/" << month << "/" << day << date;
return 0;
}
Here, you forgo parsing. Of course it means the format is hardcoded...
Here is the initial solution to what I did. Only issue is that I'm still not able to templatize it. If I do, then calling the pic formatter would look like pic<float>("$(...)", 2.56) and the code would be messy.
#include <iostream>
#include <string>
using namespace std;
class pic {
private:
const string& _v;
const string& _pic;
public:
pic(const string& p, const string& v) : _v(v), _pic(p) {
}
friend ostream & operator<<(ostream& os, const pic& p) {
bool done = false;
int pi = 0;
int vi = 0;
while (!done) {
os << (p._pic[pi] == '.' ? p._v[vi++] : p._pic[pi]);
done = ++pi > p._pic.length() || vi > p._v.length();
}
return os;
}
};
int main(int argc, char** argv) {
cout << "The formatted date is: " << pic("20../../..", "100317") << endl;
return 0;
}

Have a C++ Class act like a custom ostream, sstream

I have a C++ class MyObject and I want to be able to feed this data like I would to a osstream (but unlike a direct sstream, have the incoming data be formatted a special way). I can't seem to figure out how to overload a operator for MyObject to eat input given to it.
class MyObject {
public:
ostringstream s;
FEEDME
};
int main() {
MyObject obj;
obj.FEEDME << "Hello" << 12345;
// I want obj.s == ":Hello::12345:"
}
I want it so every item fed in be surrounded by : :
So in the given example, s = ":Hello::12345" should be the final outcome. What my question is, how can I tell the object that when ever a <<something, put : : around the something.
Is this possible?
try this:
class MyObject {
public:
template <class T>
MyObject &operator<<(const T &x) {
s << ':' << x << ':';
return *this;
}
std::string to_string() const { return s.str(); }
private:
std::ostringstream s;
};
MyObject obj;
obj << "Hello" << 12345;
std::cout << obj.to_string() << std::endl;
There are certain things you won't be able to shove into the stream, but it should work for all the basics.
You may find the answers for How do I create my own ostream/streambuf? helpful.
I would take a slightly different approach and create a formater object.
The formater object would then handle the inserting of format character when it is applied to a stream.
#include <iostream>
template<typename T>
class Format
{
public:
Format(T const& d):m_data(d) {}
private:
template<typename Y>
friend std::ostream& operator<<(std::ostream& str,Format<Y> const& data);
T const& m_data;
};
template<typename T>
Format<T> make_Format(T const& data) {return Format<T>(data);}
template<typename T>
std::ostream& operator<<(std::ostream& str,Format<T> const& data)
{
str << ":" << data.m_data << ":";
}
int main()
{
std::cout << make_Format("Hello") << make_Format(123);
}