Let's suppose I want to write my own manipulator for input and output.
cin >> mymanip >> str;
or
cout << mymanip << str;
What I want that mymanip does is toggle case the caracters I read from input and assigns the result to one string.
So, if I type "QwErTy" I get "qWeRtY" in the string.
This is a very basic task with one function, but i want to learn more about manipulators.
Can someone give a clue?
Thank you.
All that a manipulator does is set the corresponding bits in the std::ios_base base class.
For example, the std::setprecision() manipulator simply invokes std::ios_base::precision(), on the manipulated stream.
The implementation of std::setprecision() is almost readable, in gcc's headers (a rarity, for a C++ library template implementation):
inline _Setprecision setprecision(int __n)
{ return { __n }; }
std::setprecision() returns an internal std::_Precision object. Then, a simple template overload for the >> (and the << operator, which is similar) operator, for the std::_Precision object, handles the rest of the magic:
template<typename _CharT, typename _Traits>
inline basic_istream<_CharT, _Traits>&
operator>>(basic_istream<_CharT, _Traits>& __is, _Setprecision __f)
{
__is.precision(__f._M_n);
return __is;
}
In your case, there are no bits in the std::ios_base class that implement your desired input/output transformation. As such, a manipulator, per se, won't work here.
What you're trying to do requires a completely different, more complicated, approach:
A custom subclass of std::[io]stream, that uses a custom subclass of std::streambuf.
The std::streambuf subclass reads or writes from a chained stream, transforming the input or output as you've described.
Reading or writing from the custom subclass ends up reading or writing from the chained stream, transforming the data accordingly.
The way is a little tricky - but it can be done, you can add own manipulator for stream.
First, you need your toggle:
class toggle_t {};
constexpr toggle_t toggle;
Next - the version for ostream (the case for istream is very similar...):
After putting toggle to ostream - you need some special object:
struct toggled_ostream
{
std::ostream& os;
};
inline toggled_ostream operator << (std::ostream& os, toggle_t)
{
return { os };
}
Beware, that someone might put togglein wrong place: cout << toggle << 123 - so it should work for all other types as ordinary stream:
template <typename T>
std::ostream& operator << (toggled_ostream tos, const T& v)
{
return tos.os << v;
}
So - for char types (like char, const char*, std::string) write your toggle overloads. I am giving you version for char - it shouldn't be a problem to write version for "longer" types:
std::ostream& operator << (toggled_ostream tos, char v)
{
char c = std::isupper(v) ? std::tolower(v)
: std::islower(v) ? std::toupper(v) : v;
return tos.os << c;
}
Working demo.
You cannot do that. What you can do instead are manipulators that would take the string as argument, i.e.
std::cout << toggle(str);
std::cin >> toggle(str);
A manipulator is only ever so-called syntactic sugar, i.e. it can do things more conveniently than otherwise. For example,
std::cout << std::setw(5) << x <<;
will do the same as
std::cout.width(5);
std::cout << x;
but is more convenient as it allows to be chained together with other << operations.
Now, there is no formatting support of the thing you want (swap lower and upper case characters), and hence also no way to provide syntactic sugar for that.
However, if the manipulator can take your string as an argument, then of course, you can achieve what you want, implemented in the standard way of manipulator implementation. For example,
struct toggle_output
{ std::string const&str; }
inline toggle_output toggle(std::string const&str)
{ return {str}; }
inline std::ostream& operator<<(std::ostream&out, toggle_output const&t)
{
for(auto c:t.str)
if (std::islower(c)) out<<std::toupper(c);
else if(std::isupper(c)) out<<std::tolower(c);
else out<<c;
return out;
}
struct toggle_input
{ std::string &str; }
inline toggle_input toggle(std::string&str)
{ return {str}; }
inline std::istream& operator>>(std::istream&in, toggle_input &t)
{
in >> t.str;
for(auto&c:t.str)
if (std::islower(c)) c=std::toupper(c);
else if(std::isupper(c)) c=std::tolower(c);
return in;
}
You may also need (to avoid confusion)
inline std::ostream& operator<<(std::ostream&out, toggle_input const&t)
{ return out<<toggle_output(t.str); }
As other answers explain, manipulators simply mimic existing std::ios_base functionality.
There's a simple solution to your problem, though I'm not sure if this can be called a manipulator:
struct toggle_in_helper
{
std::string & res;
};
toggle_in_helper toggle (std::string & res)
{
return {res};
}
std::istream & operator >> (std::istream & in, toggle_in_helper h)
{
in >> h.res;
for (auto & c : h.res)
// toggle the case of 'c'
;
return in;
}
That is, we create a helper class toggle_in_helper with overloaded operator >> which does the job.
Related
I've got a template class derived from std::basic_stringstream<typename TString::value_type...>, as you can see. The problem happens while trying to convert them. It's probably an obvious problem, though I cannot seem to figure out the solution.
As example in main, I have a simple std::wstring and initialize it with L"123".
After the std::wstring has been constructed, the operator of the custom basic_stringstream class is called (depending on std::wstring or std::string).
Inspecting the WCStringStream object for debugging purposes, shows that it contains - instead of the string L"123", the address of the first element of the entered string. The functions to_bytes and from_bytes do return the correct converted string, so the only problem left is the operator being called in both operator-functions:
*this << std::wstring_convert<...>().xx_bytes(s);
Example:
Template class is std::wstring.
Input is a std::string.
&operator<<(const std::string &s) is being called.
String is converted.
&operator<<(const std::wstring &s) is being called.
String-type matches with template type.
Operator of base-class (basic_stringstream) is called. (Or std::operator...)
Result:
Inspecting: {_Stringbuffer={_Seekhigh=0x007f6808 L"003BF76C췍췍췍췍췍췍췍췍췍...}...}
WCStringStream<std::wstring>::str() -> "003BF76C"
Expected result:
"123"
What's going wrong here ?
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#include <Windows.h>
#include <iostream>
#include <sstream>
#include <codecvt>
template<class TString>
class WCStringStream : public std::basic_stringstream<typename TString::value_type,
std::char_traits<typename TString::value_type>,
std::allocator<typename TString::value_type> >
{
typedef typename TString::value_type CharTraits;
typedef std::basic_stringstream<CharTraits, std::char_traits<CharTraits>, std::allocator<CharTraits> > MyStream;
//more typedefs...
public:
//Constructor...
inline WCStringStream(void) { }
inline WCStringStream(const TString &s) : MyStream(s) { }
//and more...
//operator>> overloads...
//defines for VS2010/2015 (C++11) included
inline WCStringStream &operator<<(const std::wstring &s)
{
if (typeid(TString) == typeid(s))
MyStream::operator<<(s.c_str());
else
*this << std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t>().to_bytes(s);
return *this;
}
inline WCStringStream &operator<<(const std::string &s)
{
if (typeid(TString) == typeid(s))
MyStream::operator<<(s.c_str());
else
*this << std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t>().from_bytes(s);
return *this;
}
};
//Example main
int main(int argc, char *argv[])
{
typedef std::wstring fstring;
WCStringStream<std::wstring> ws;
WCStringStream<std::string> ss;
ws << fstring(L"123");
int a = 0;
ws >> a;
std::cout << a << std::endl;
ss << fstring(L"123");
int b = 0;
ss >> b;
std::cout << b << std::endl;
return 0;
}
I'm compiling currently in VS2015 but I'd need it to run on VS2010 too.
First off: I think the approach to overload formatting function in a base class is ill-advised and I strongly recommend to not do it! I do realize that any alternative will require a bit more work.
In fact, I think your primary problem is actually that you do not reach your overloaded functions anyway just showing how fragile the approach is (I think the string describe what overload ends up being called but I haven't verified that these are indeed accurate, partly because the code provided in the question is lacking necessary context):
WCStringStream<std::string> stream;
stream << "calls std::operator<< (std::ostream&, char const*)\n";
stream << L"calls std::ostream::operator<< (void const*)\n";
stream << std::string("calls std::operator<< (std::ostream&, T&&)\n";
std::string const s("calls your operator\n");
stream << s;
Since the overloaded output operators for strings and string literals can't be changed and they do the wrong think with respect to code conversions, I recommend using an entirely different approach although it still won't be without peril(*): convert the strings explicitly although using a more nicely packaged version of the code than the standard provides.
Assuming always using char as character type for all uses I would use a function wcvt() which is called for all strings and string-literals when inserting them into a stream. Since at the point the function is being called it wouldn't know the type of the stream it is going to be used with, it would return essentially a reference to the character sequence which is then converted appropriately for the character type used for the stream. That would be something along these lines:
template <typename cT>
class wconvert {
cT const* begin_;
cT const* end_;
public:
wconvert(std::basic_string<cT> const& s)
: begin_(s.data())
, end_(s.data() + s.size()) {
}
wconvert(cT const* s)
: begin_(s)
, end_(s + std::char_traits<cT>::length(s)) {
}
cT const* begin() const { return this->begin_; }
cT const* end() const { return this->end_; }
std::streamsize size() const { return this->end_ - this->begin_; }
};
template <typename cT>
wconvert<cT> wcvt(cT const* s) {
return wconvert<cT>(s);
}
template <typename cT>
wconvert<cT> wcvt(std::basic_string<cT> const& s) {
return wconvert<cT>(s);
}
template <typename cT>
std::basic_ostream<cT>& operator<< (std::basic_ostream<cT>& out,
wconvert<cT> const& cvt) {
return out.write(cvt.begin(), cvt.size());
}
std::ostream& operator<< (std::ostream& out, wconvert<wchar_t> const& cvt) {
auto tmp = std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t>().to_bytes(cvt.begin(), cvt.end());
return out.write(tmp.data(), tmp.size());
}
std::wostream& operator<< (std::wostream& out, wconvert<char> const& cvt) {
auto tmp = std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t>().from_bytes(cvt.begin(), cvt.end());
return out.write(tmp.data(), tmp.size());
}
Of course, using this approach requires the use of wcvt(s) whenever s may be a string which needs to be converted. It is easy to forget doing so and it seems the original objective was to not have to remember the use of such a conversion. However, I don't see any alternative which is less fragile with the system of existing streams. Entirely abandoning the use of streams and using an entirely separate system of formatted I/O may yield less fragile approach.
(*) The approach easiest to get right is to stick with just on character type in a program and always using this character type. I do believe it was actually an error to introduce a second character type, wchar_t, and it an even bigger error to further complicate the existing mess by having also introduced char16_t and char32_t. We'd be much better off there were just one character type, char, although it actually wouldn't represent character but bytes of an encoding.
The problem was to explicitly call the base class operator, which takes the const void *_Val overload and prints the address.
MyStream::operator<<(s.c_str());
The solution to the problem:
if (typeid(TString) == typeid(s))
{
MyStream &os = *this;
os << s.c_str();
}
Of course calling *this << s.c_str() results in recursion, but the using the base class, it calls the global overloaded operator for the correct char-type wchar_t / char.
An also working solution is to use the member-function write instead of the operator.
I'm trying to create some I/O manipulators to allow a user to modify the output format of a custom type.
Say I have a Foo object: I might want to either output it in a nice, human-readable format (pretty printing), or I might want to print it in a condensed form to save space when serialized.
So, it would be nice to have custom I/O manipulators like condensed and pretty that would modify the internal flags of a facet, so I could say something like:
Foo f;
...
std::cout << pretty << f; // output human-readable format
std::cout << condensed << f; // output condensed format
The problem I always run into is the fact that once a facet object is created, it can only be retrieved later by using std::use_facet, which returns a const reference. This means I can't later modify any of the internal facet flags.
Consider a simple facet:
class my_facet : public std::locale::facet
{
public:
my_facet() : m_pretty(false), m_condensed(false)
{ }
void set_pretty(bool b) { m_pretty = b; }
void set_condensed(bool b) { m_condensed = b; }
static std::locale::id id;
private:
bool m_pretty;
bool m_condensed;
};
I could then create I/O manipulators like:
template <class CharT, class Traits>
inline std::basic_ostream<CharT, Traits>& pretty(std::basic_ostream<CharT, Traits>& os)
{
my_facet<CharT>* facet = new my_facet();
facet->set_pretty(true);
facet->set_condensed(false);
std::locale loc = std::locale(os.getloc(), facet);
os.imbue(loc);
return os;
}
That works nicely... but what if I want to allow the user to specify additional flags or formatting options, like say, an indentation option that allows the user to specify a number of spaces to indent, like this:
std::cout << pretty << indent(4) << f;
The problem is that each I/O manipulator has to recreate the facet object, and so previous flags set are lost. The reason is that there's no way to access a non-const reference to the existing facet.
I want to say:
template <class CharT, class Traits>
inline std::basic_ostream<CharT, Traits>& operator << (std::basic_ostream<CharT, Traits>& os,
const indent& ind)
{
const my_facet<CharT>& facet = std::use_facet<my_facet>(os.getloc());
facet.set_indentation(ind.value()); // Error: facet is const!
return os;
}
...but of course, that won't work, because facet is const. The only way I can see around this is making all internal flags mutable, which is absurd.
So, I'm sensing that I'm just doing this wrong. There doesn't seem to be any way to get a non-const reference to an existing facet, so I think I'm going about this whole thing the wrong way.
So, how is this sort of thing usually achieved? How can I write I/O manipulators that can be chained together to set different flags, like:
std::cout << pretty << indent(3) << etc ...
The accepted way of storing custom formatting state is with memory allocated by std::ios_base::xalloc. For example (abridged, live demo with full code here):
class MyFancyManipulator
{
static int myidx;
int st;
public:
MyFancyManipulator(int st) : st(st) {};
template <typename Ch, typename Tr> friend
std::basic_ostream<Ch, Tr>& operator<< (std::basic_ostream<Ch, Tr>& str,
const MyFancyManipulator& man) {
//
// Transfer state from the manipulator to the stream
//
str.iword(MyFancyManipulator::myidx) = man.st;
return str;
}
};
// Allocate index for the state variable
// This is thread safe per C++14 standard
int MyFancyManipulator::myidx = std::ios_base::xalloc();
// ... In some custom operator<<
int state = str.iword(MyFancyManipulator::myidx);
How to implement ostream-like class from scratch using printf only?
For me looks like the problem is in choosing the format string ,which is actually equal to the identifying input`s type and treating precision
I assume you mean something that overloads operator<< by "an ostream-like class". It's easy to identify the type of the argument to a function just by having overloads. For example, you might have:
ostreamlike& ostreamlike::operator<<(int x)
{
printf("%d", x);
return *this;
}
ostreamlike& ostreamlike::operator<<(float x)
{
printf("%f", x);
return *this;
}
The format of the output is determined by whichever overload is picked.
Think, it could be something like that
#include <stdio.h>
class ostreamlike {
public:
ostreamlike(FILE* f_): f(f_) {}
ostreamlike& write(int n) {
fprintf(f, "%d", n);
return *this;
}
ostreamlike& write(const char* n) {
fprintf(f, "%s", n);
return *this;
}
private:
FILE* f;
};
// operator for types that is supported ostreamlike internally
template <typename type>
ostreamlike& operator<<(ostreamlike& stream, const type& data) {
return stream.write(data);
}
// external implementations to write using ostreamlike
ostreamlike& operator<<(ostreamlike& stream, bool data) {
return stream.write(data ? "true" : "false");
}
int main() {
ostreamlike s(stdout);
s << "hello " << 1 << " : " << true << "\n";
return 0;
}
It depends on how close to the real ostream you want to be. Assuming you want to do it properly you would also need a streambuf derived class. ostream only does the formatting, the actual I/O is done by an internal streambuf derived class. Since streambuf does unformatted I/O you would need to use fwrite not printf.
If your goal is just to do I/O on an already existing FILE* pointer this is the way to go. You derive one class from streambuf, say streambuf_with_FILE and then you derive another class from ostream say ostream_with_FILE. streambuf_with_FILE overrides the appropriate methods to do the actual I/O and ostream_with_FILE has an internal streambuf_with_FILE object. There's actually very little code required.
There is the complex<> template in C++ standard library, and it has an overloaded << operator so that it outputs complex numbers in the (real_part, im_part) format. I need to change the behavior of that operator for complex numbers so that the output format is changed to something completely different. Specifically, I need the output to be in the form real_part\tim_part. How do I do that?
There's no direct way to replace operator <<, but you do have a few options. First, you could just write your own function to print complex numbers:
template <typename T> void PrintComplex(const complex<T>& c) {
/* ... */
}
If you want to still use the nice stream syntax, then one trick you could do would be to make a wrapper class that wraps a complex and then defines its own operator << that prints it out in a different way. For example:
template <typename T> class ComplexPrinter {
public:
/* Conversion constructor allows for implicit conversions from
* complex<T> to ComplexPrinter<T>.
*/
ComplexPrinter(const complex<T>& value) : c(value) {
// Handled in initializer list
}
/* Output the complex in your own format. */
friend ostream& operator<< (ostream& out, const ComplexPrinter& cp) {
/* ... print in your own format ... */
}
private:
complex<T> c;
};
Once you have this, you could write something like
cout << ComplexPrinter<double>(myComplex) << endl;
You can make this even cleaner by writing a function like this one to wrap the object for you:
template <typename T>
ComplexPrinter<T> wrap(const complex<T>& c) {
return ComplexPrinter<T>(c);
}
This then lets you write
cout << wrap(myComplex) << endl;
Which isn't perfect, but is pretty good.
One thing to note about the above wrapper is that it has an implicit conversion constructor set up to let you convert complex<T>s to ComplexPrinter<T>s. This means that if you have a vector< complex<T> >, you can print it out using your custom code by calling
vector< complex<double> > v = /* ... */
copy (v.begin(), v.end(), ostream_iterator< ComplexPrinter<double> >(cout, " "));
On output, the implicit conversion constructor will transform your complex<double>s into the wrappers, and your custom code will do the printing for you.
If you want to be very adventurous and cast caution to the wind, you could even write the class so that it just stores a reference to the original complex, as shown here:
template <typename T> class ComplexPrinter {
public:
/* Conversion constructor allows for implicit conversions from
* complex<T> to ComplexPrinter<T>.
*/
ComplexPrinter(const complex<T>& value) : c(value) {
// Handled in initializer list
}
/* Output the complex in your own format. */
friend ostream& operator<< (ostream& out, const ComplexPrinter& cp) {
/* ... print in your own format ... */
}
private:
const complex<T>& c;
};
This completely eliminates any copying and just makes the wrapper a thin veneer around a real complex. (No pun intended). You'd have to be very careful if you did this not to pass these objects around across scope boundaries where the original objects go out of scope, but if it's what you want it might work out just great.
Hope this helps!
template<class T>
struct my_complex_format_type {
std::complex<T> const &x;
my_complex_format_type(std::complex<T> const &x) : x (x) {}
friend std::ostream& operator<<(std::ostream &out,
my_complex_format_type const &value)
{
out << "format value.x however you like";
return out;
}
};
template<class T>
my_complex_format_type<T> my_complex_format(std::complex<T> const &x) {
return x;
}
void example() {
std::cout << my_complex_format(some_complex);
}
For any specific instantiation of complex<T>, Use a strong typedef (boost has a version) and cast to that type during << calls. Override << for that type.
If you need to override << for any variation of complex<T> then life will be harder.
My answer to the same question here: c++ display complex number with i in imaginary part produces the behavior you want, at the expense of some risk of future incompatibility because it inserts a template specialization into the std:: namespace.
There is no really tidy way to do that. My suggestion would be to just ditch iostreams and write something more C-like instead. It will probably be faster to write, faster to read and faster to execute.
Is there a way to use these operators to input and output binary data? The reason I want to do this is that it makes the code readable.
Ex: infile >> filedecrypter >> metadataparser >> audiodecoder >> effects >> soundplayer;
Just to be clear, are you intending to duplicate the semantics of iostreams? Because it looks like you are proposing something different. In the example you give:
infile >> filedecrypter >> metadataparser >> audiodecoder >> effects >> soundplayer;
In iostreams, the meaning here is to read from infile into filedecrypter until you get to whitespace, and then from infile into metadataparser until more whitespace, and so on.
It looks like you are proposing something different, where metadataparser reads from filedecrypter, audiodecoder from metadataparser, etc. In which case I think the answer to your question needs to be qualified a bit.
Can you use operator >> to express this construct? Probably yes.
Can you use iostreams for this? Probably not.
I suggest you clarify what it means when you say A >> B. Perhaps express it as regular methods rather than operator overloads first, and that may clarify the question.
Indeed that can be done, if the library or your code provides the overloads for operator<< and operator>> for it to work. Simple example on how one could do it:
class transformer {
public:
virtual std::iostream& transform(std::iostream&) = 0;
};
class noise : public transformer {
public:
virtual std::iostream& transform(std::iostream&) {
/* extract, change and put into again */
}
};
class echo : public transformer {
public:
virtual std::iostream& transform(std::iostream&) {
/* extract, change and put into again */
}
};
std::iostream& operator>>(std::iostream& io, transformer& ts) {
return ts.transform(io);
}
int main() {
std::stringstream data;
std::ifstream file("sound.wav");
noise n; echo e;
data << file.rdbuf();
data >> n >> e;
/* pipelined data now ready to be played back */
}
The problem with using a pure std::istream is that you would read, but then you wouldn't have a way to put the transformed data back for the next step in the pipeline. Thus i'm using std::iostream here. This approach doesn't seem to be efficient, as every operator>> call would extract the whole data, and put into again.
To have a more performant way to stream this would be to create an expression template. This means, while operator>> is called, you don't do the transforming yet, but you return expression types that will record the chain of operations within its type:
typedef transform< echo< noise< istream > > > pipeline;
std::ifstream file("file.wav");
pipeline pipe(file);
int byte = pipe.get();
would be an example of such a type. The pipelines' structure is decoded into the type itself. Therefore, no virtual functions are needed anymore in the pipeline. It's not constructed on-demand, but using typedef here, to show the principle. Programming such a system is not easy. So you probably should look into existing systems, like Boost.Iostreams (see below). To give you an idea how it would look like, here is an example i just coded up for you :) :
#include <iostream>
template<typename T>
struct transformer {
int get() {
return static_cast<T*>(this)->read();
}
};
struct echot {
template<typename Chain>
struct chain : transformer< chain<Chain> > {
Chain c;
int read() {
return c.get() + 1;
}
chain(Chain const& c):c(c) { }
};
} echo;
struct noiset {
template<typename Chain>
struct chain : transformer< chain<Chain> > {
Chain c;
int read() {
return c.get() * 2;
}
chain(Chain c):c(c) { }
};
} noise;
template<typename T>
typename T::template chain<std::istream&> operator>>(std::istream& is, T) {
return typename T::template chain<std::istream&>(is);
}
template<typename T, typename U>
typename U::template chain<T> operator>>(T t, U u) {
return typename U::template chain<T>(t);
}
int main() {
std::cout << (std::cin >> echo >> noise).get() << std::endl;
}
Entering 0 yields the ASCII code 48 here, which is added 1, and multiplied by 2, yielding a value of 98, which is also finally output. I think you agree this is not some code a starter would want to write. So maybe look into boost.
Boost has an sophisticated iostreams library, which can do many things. I'm sure you would find something fitting to this. Boost.Iostreams
Sure it can be done. Just define your own operator>> and operator<< so they do "the right thing"...
I would make it so I would have methods in the class, like toStream(ostream& os) and fromStream(istream& ), then define
istream& operator>> (istream& is, T& t)
{
t.fromStream(is);
return t;
}
ostream& operator<< (ostream& os, const T& t)
{
t.toStream(os);
return t;
}
There is no need to use streams to move the data. You can create your own classes to do this. This shows an example. Obviously, the Decrypt and MetaDataParser classes can be abstract base classes with virtual functions to allow various functionality be plugged together.
#include <iostream>
#include <istream>
using namespace std;
class Data2
{
};
class Data3
{
};
class Decrypt
{
};
class MetaDataParser
{
};
Data2& operator>>(istream& in, Decrypt& decrypt)
{
return *new Data2;
}
Data3& operator>>(Data2& d2, MetaDataParser& mdp)
{
return *new Data3;
}
int main()
{
Decrypt decrypt;
MetaDataParser mdp;
cin >> decrypt >> mdp;
}