Using various format specifiers of c in c++ - c++

As in c we can use various format specifiers like
%nd where n is a number, to print the number with a total of atleast n space covered
%0nd same as above, except pre-padding with 0's " %05d ",3 => 00003
%.nf to set precision of n after decimal
etc ....
So is there any way to use these with std::cout ?
I got some negative feedback in a recent course (c++ for c programmers) in coursera, for using printf instead of cout because i wanted to some formatting :(

For %nd %0nd, C++ equivalents are std::setw() and std::setfill().
#include <iostream> // std::cout, std::endl
#include <iomanip> // std::setfill, std::setw
int main () {
std::cout << std::setfill ('x') << std::setw (10);
std::cout << 77 << std::endl;
return 0;
}
Output: xxxxxxxx77
%.nf can be replaced by std::setprecision and std::fixed,
#include <iostream> // std::cout, std::fixed, std::scientific
int main () {
double a = 3.1415926534;
double b = 2006.0;
double c = 1.0e-10;
std::cout.precision(5);
std::cout << "fixed:\n" << std::fixed;
std::cout << a << '\n' << b << '\n' << c << '\n';
return 0;
}
Output:
fixed:
3.14159
2006.00000
0.00000

C++ streams don't use format-specifiers like C's printf()-type functions; they use manipulators.
For example:
#include <iostream>
#include <iomanip>
int main()
{
std::cout << std::fixed << std::setprecision(6) << 42.0 << std::endl;
}
Output:
42.000000
See it run!

The usual solution in C++ is to defined manipulators which state
what your trying to format, rather than to hack physical values
directly at the point of output. (One possible exception is the
width, where std::setw may be useful directly.) Thus, for
example, when actually outputting something, you won't specify
zero padding, or fixed, with 2 decimals, but something like:
std::cout << temperature(2) << theTemporature;
where temperature would be something like:
class temperature
{
int myMinWidth;
public:
temperature( int minWidth )
: myMinWidth( minWidth )
{
}
friend std::ostream& operator<<( std::ostream& dest, temperature const& manip )
{
dest.setf( std::ios_base::fixed, std::ios_base::floatfield );
dest.precision( 2 );
dest.width( myMinWidth );
return dest;
}
};
For the list of format modifications available, see the
specification of std::ios_base, and the fields of
std::ios_base::fmtflags.
If you're doing a lot of output, you might want to modify this
to restore the original format flags at the end of the full
expression. (All of the format information except the width is
sticky, so forcing fixed format here leaves you with fixed
format for the rest of the program, which isn't necessarily what
you want.) I use the following as base class for all of my
manipulators:
class StateSavingManip
{
public:
void operator()( std::ios& stream ) const;
protected:
StateSavingManip() : myStream( nullptr ) {}
~StateSavingManip();
private:
virtual void setState( std::ios& stream ) const = 0;
private:
mutable std::ios* myStream;
mutable std::ios::fmtflags mySavedFlags;
mutable int mySavedPrec;
mutable char mySavedFill;
};
implementation:
namespace {
int getXAlloc() ;
int ourXAlloc = getXAlloc() + 1 ;
int
getXAlloc()
{
if ( ourXAlloc == 0 ) {
ourXAlloc = std::ios::xalloc() + 1 ;
assert( ourXAlloc != 0 ) ;
}
return ourXAlloc - 1 ;
}
}
StateSavingManip::~StateSavingManip()
{
if ( myStream != nullptr ) {
myStream->flags( mySavedFlags ) ;
myStream->precision( mySavedPrec ) ;
myStream->fill( mySavedFill ) ;
myStream->pword( getXAlloc() ) = NULL ;
}
}
void
StateSavingManip::operator()(
std::ios& stream ) const
{
void*& backptr = stream.pword( getXAlloc() ) ;
if ( backptr == nullptr ) {
backptr = const_cast< StateSavingManip* >( this ) ;
myStream = &stream ;
mySavedFlags = stream.flags() ;
mySavedPrec = stream.precision() ;
mySavedFill = stream.fill() ;
}
setState( stream ) ;
}
Note the use of the pword field to ensure that only the first
temporary manipulator restores the format; the destructors will
be called in the reverse order of construction, but the order of
construction will typically not be specified if you have more
than one such manipulator in an expression.
Finally: not everything is possible using this technique: if you
want to systematically append a degree sign to the temperature,
there's no way of doing so. In this case, you need to define
a class Temperature, and overload the << operator for it; this
allows everything imaginable (much more than you could ever
achieve with printf style formatting).

C++ stream manipulators (iomanip) were specifically designed to support all of the standard c format specifiers operations, just with an entirely different interface. E.g. setfill and setw for the width and fill part of %02d.
Of course if you really need format strings (e.g. because it makes i18n easier for you), then you should have a look at boost::format, and if you have C++11 then you can easily write small variadic template wrapper around it, to make the format call look more like printf.
Whatever you do, please try to not use printf. It is not typesafe, and not extendible for output operations on user defined types.

There are stream manipulators, if you need them. But I think you want to know this thing: cout is smarter than printf().
Say you have:
int x = 34;
cout<<x;
Now the compiler will call:
ostream& operator<<(ostream& stream, int arg);
for you. And this function will print the output in console( since in your case stream is cout). The standard library supplies overloads for this << operator for all fundamental datatype available.

Related

Unexpected results from ios_base::xalloc() and ostream::iword() (iomanip)

My goal is to have an iomanip inserter with parameter that can be used to determine if a message will be printed to the stream (or not.) The idea is that a static mask will include bits set for the categories of messages that should be streamed (and bits cleared for messages to be discarded.) The inserter will be used to specify what category (or categories) a message belongs to and if the mask anded with the presented categories is not zero, the message would be streamed out. I have this working but with file scope mask and categories. It seems to me that (at least the category) could be stored with the stream using xalloc() to provide an index and iword() to store/retrieve values at that index but that seems not to be working for me. I have read various Internet references for these functions and my expectation is that sequential calls to xalloc() should return increasing values. In the code below the value returned is always 4. My second puzzlement is where the storage for the iword() backing store is held. Is this static for ostream? Part of every ostream object?
Code follows
#include <iostream>
#include <sstream>
// from http://stackoverflow.com/questions/2212776/overload-handling-of-stdendl
//
// g++ -o blah blah.cpp
//
// Adding an iomanip with argument as in
// http://stackoverflow.com/questions/20792101/how-to-store-formatting-settings-with-an-iostream
//
using namespace std;
// don't really want file scope variables... Can these be stored in stream?
static int pri=0; // value for a message
static int mask=1; // mask for enabled output (if pri&mask => output)
static int priIDX() { // find index for storing priority choice
static int rc = ios_base::xalloc();
return rc;
}
class setPri // Store priority in stream (but how to retrieve when needed?)
{
size_t _n;
public:
explicit setPri(size_t n): _n(n) {}
size_t getn() const {return _n;}
friend ostream& operator<<(ostream& os, const setPri& obj)
{
size_t n = obj.getn();
int ix = priIDX();
pri = os.iword(ix) = n; // save in stream (?) and to file scope variable
os << "setPri(" << n << ") ix:" << ix << " "; // indicate update
return os;
}
};
class MyStream: public ostream
{
// Write a stream buffer that discards if mask & pri not zero
class MyStreamBuf: public stringbuf
{
ostream& output;
public:
MyStreamBuf(ostream& str)
:output(str)
{}
// When we sync the stream with the output.
// 1) report priority mask (temporary)
// 2) Write output if same bit set in mask and priority
// 3) flush the actual output stream we are using.
virtual int sync ( )
{
int ix = priIDX();
int myPri(output.iword(ix));
output << "ix:" << ix << " myPri:" << myPri << '\n';
if( mask & pri) // can't use (myPri&mask)
output << ' ' << str();
str("");
output.flush();
return 0;
}
};
// My Stream just uses a version of my special buffer
MyStreamBuf buffer;
public:
MyStream(ostream& str)
:buffer(str)
{
rdbuf(&buffer);
}
};
int main()
{
MyStream myStream(cout);
myStream << setPri(1) << " this should output" << endl;
myStream << setPri(2) << " this should not output" << endl;
myStream << setPri(3) << " this should also output" << endl;
}
Note that in sync() the code tries to fetch the value from the stream but the returned value is always 0 as if it was not set to begin with.
In my searches to get to this point I have seen comments that it is not a good idea to subclass an ostream. Feel free to suggest a better alternative! (That I can understand. ;) )
Thanks!
static int priIDX() { // find index for storing priority choice
static int rc = ios_base::xalloc();
return rc;
}
This will always return the same value, as your value is static. And therefore only initialized on the first call.
The storage for the iword data is dynamic and allocated separately by each stream object whenever something is stored there.

C++ Character Array Error Handling

If I declare a string array in c++ such as
char name[10]
how would you error handle if the input is over the character limit?
Edit: My assignment says to use cstring rather than string. Input will be the person's full name.
Here is an example where setName checks the size is OK before assigning the char[10] attribute.
Note char[10] can only store a 9-characters name, because you need one character to store the end-of-string.
Maybe that's what you want:
#include <iostream>
#include <cstring>
using namespace std;
#define FIXED_SIZE 10
class Dummy
{
public:
bool setName( const char* newName )
{
if ( strlen( newName ) + 1 > FIXED_SIZE )
return false;
strcpy( name, newName );
return true;
}
private:
char name[FIXED_SIZE];
};
int main()
{
Dummy foo;
if ( foo.setName( "ok" ) )
std::cout << "short works" << std::endl;
if ( foo.setName( "012345678" ) )
std::cout << "9 chars OK,leavs space for \0" << std::endl;
if ( !foo.setName( "0123456789" ) )
std::cout << "10 chars not OK, needs space for \0" << std::endl;
if ( !foo.setName( "not ok because too long" ) )
std::cout << "long does not work" << std::endl;
// your code goes here
return 0;
}
I'm piecing together that your instructions say to use <cstring> so you can use strlen to check the length of the string prior to "assigning" it to your name array.
so something like...
const int MAX_NAME_LEN = 10;
char name[MAX_NAME_LEN];
// ...
// ...
if (strlen(input)+1 >= MAX_NAME_LEN) {
// can't save it, too big to store w/ null char
}
else {
// good to go
}
First of all your question is not clear. Anyway I assume you want to ask for a way to ensure array index does not get out of bound.
Anything outside of that range causes undefined behavior. If the index was near the range, most probably you read your own program's memory. If the index was largely out of range, most probably your program will be killed by the operating system.
That means undefined behaviour could mean program crash, correct output etc.
Since others mentioned how to do this with a predefined input string, here's a solution which reads a c-string from input:
#include <iostream>
#define BUF_SIZE 10
using namespace std;
int main()
{
char name[BUF_SIZE];
cin.get(name, BUF_SIZE-1);
if (cin) //No eof
if (cin.get() != '\n')
cerr << "Name may not exceed " << BUF_SIZE-1 << " characters";
}

Custom stream manipulator for streaming integers in any base

I can make an std::ostream object output integer numbers in hex, for example
std::cout << std::hex << 0xabc; //prints `abc`, not the base-10 representation
Is there any manipulator that is universal for all bases? Something like
std::cout << std::base(4) << 20; //I want this to output 110
If there is one, then I have no further question.
If there isn't one, then can I write one? Won't it require me to access private implementation details of std::ostream?
Note that I know I can write a function that takes a number and converts it to a string which is the representation of that number in any base. Or I can use one that already exists. I am asking about custom stream manipulators - are they possible?
You can do something like the following. I have commented the code to explain what each part is doing, but essentially its this:
Create a "manipulator" struct which stores some data in the stream using xalloc and iword.
Create a custom num_put facet which looks for your manipulator and applies the manipulation.
Here is the code...
Edit: Note that im not sure I handled the std::ios_base::internal flag correctly here - as I dont actually know what its for.
Edit 2: I found out what std::ios_base::internal is for, and updated the code to handle it.
Edit 3: Added a call to std::locacle::global to show how to make all the standard stream classes support the new stream manipulator by default, rather than having to imbue them.
#include <algorithm>
#include <cassert>
#include <climits>
#include <iomanip>
#include <iostream>
#include <locale>
namespace StreamManip {
// Define a base manipulator type, its what the built in stream manipulators
// do when they take parameters, only they return an opaque type.
struct BaseManip
{
int mBase;
BaseManip(int base) : mBase(base)
{
assert(base >= 2);
assert(base <= 36);
}
static int getIWord()
{
// call xalloc once to get an index at which we can store data for this
// manipulator.
static int iw = std::ios_base::xalloc();
return iw;
}
void apply(std::ostream& os) const
{
// store the base value in the manipulator.
os.iword(getIWord()) = mBase;
}
};
// We need this so we can apply our custom stream manipulator to the stream.
std::ostream& operator<<(std::ostream& os, const BaseManip& bm)
{
bm.apply(os);
return os;
}
// convience function, so we can do std::cout << base(16) << 100;
BaseManip base(int b)
{
return BaseManip(b);
}
// A custom number output facet. These are used by the std::locale code in
// streams. The num_put facet handles the output of numberic values as characters
// in the stream. Here we create one that knows about our custom manipulator.
struct BaseNumPut : std::num_put<char>
{
// These absVal functions are needed as std::abs doesnt support
// unsigned types, but the templated doPutHelper works on signed and
// unsigned types.
unsigned long int absVal(unsigned long int a) const
{
return a;
}
unsigned long long int absVal(unsigned long long int a) const
{
return a;
}
template <class NumType>
NumType absVal(NumType a) const
{
return std::abs(a);
}
template <class NumType>
iter_type doPutHelper(iter_type out, std::ios_base& str, char_type fill, NumType val) const
{
// Read the value stored in our xalloc location.
const int base = str.iword(BaseManip::getIWord());
// we only want this manipulator to affect the next numeric value, so
// reset its value.
str.iword(BaseManip::getIWord()) = 0;
// normal number output, use the built in putter.
if (base == 0 || base == 10)
{
return std::num_put<char>::do_put(out, str, fill, val);
}
// We want to conver the base, so do it and output.
// Base conversion code lifted from Nawaz's answer
int digits[CHAR_BIT * sizeof(NumType)];
int i = 0;
NumType tempVal = absVal(val);
while (tempVal != 0)
{
digits[i++] = tempVal % base;
tempVal /= base;
}
// Get the format flags.
const std::ios_base::fmtflags flags = str.flags();
// Add the padding if needs by (i.e. they have used std::setw).
// Only applies if we are right aligned, or none specified.
if (flags & std::ios_base::right ||
!(flags & std::ios_base::internal || flags & std::ios_base::left))
{
std::fill_n(out, str.width() - i, fill);
}
if (val < 0)
{
*out++ = '-';
}
// Handle the internal adjustment flag.
if (flags & std::ios_base::internal)
{
std::fill_n(out, str.width() - i, fill);
}
char digitCharLc[] = "0123456789abcdefghijklmnopqrstuvwxyz";
char digitCharUc[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const char *digitChar = (str.flags() & std::ios_base::uppercase)
? digitCharUc
: digitCharLc;
while (i)
{
// out is an iterator that accepts characters
*out++ = digitChar[digits[--i]];
}
// Add the padding if needs by (i.e. they have used std::setw).
// Only applies if we are left aligned.
if (str.flags() & std::ios_base::left)
{
std::fill_n(out, str.width() - i, fill);
}
// clear the width
str.width(0);
return out;
}
// Overrides for the virtual do_put member functions.
iter_type do_put(iter_type out, std::ios_base& str, char_type fill, long val) const
{
return doPutHelper(out, str, fill, val);
}
iter_type do_put(iter_type out, std::ios_base& str, char_type fill, unsigned long val) const
{
return doPutHelper(out, str, fill, val);
}
};
} // namespace StreamManip
int main()
{
// Create a local the uses our custom num_put
std::locale myLocale(std::locale(), new StreamManip::BaseNumPut());
// Set our locacle to the global one used by default in all streams created
// from here on in. Any streams created in this app will now support the
// StreamManip::base modifier.
std::locale::global(myLocale);
// imbue std::cout, so it uses are custom local.
std::cout.imbue(myLocale);
std::cerr.imbue(myLocale);
// Output some stuff.
std::cout << std::setw(50) << StreamManip::base(2) << std::internal << -255 << std::endl;
std::cout << StreamManip::base(4) << 255 << std::endl;
std::cout << StreamManip::base(8) << 255 << std::endl;
std::cout << StreamManip::base(10) << 255 << std::endl;
std::cout << std::uppercase << StreamManip::base(16) << 255 << std::endl;
return 0;
}
Custom manipulators are indeed possible. See for example this question. I'm not familiar with any specific one for universal bases.
You really have two separate problems. The one I think you're asking about is entirely solvable. The other, unfortunately, is rather less so.
Allocating and using some space in the stream to hold some stream state is a problem that was foreseen. Streams have a couple of members (xalloc, iword, pword) that let you allocate a spot in an array in the stream, and read/write data there. As such, the stream manipulator itself is entirely possible. You'd basically use xalloc to allocate a spot in the stream's array to hold the current base, to be used by the insertion operator when it converts a number.
The problem for which I don't see a solution is rather simpler: the standard library already provides an operator<< to insert an int into a stream, and it obviously does not know about your hypothetical data to hold the base for a conversion. You can't overload that, because it would need exactly the same signature as the existing one, so your overload would be ambiguous.
The overloads for int, short, etc., however, are overloaded member functions. I guess if you wanted to badly enough, you could get by with using a template to overload operator<<. If I recall correctly, that would be preferred over even an exact match with a non-template function as the library provides. You'd still be breaking the rules, but if you put such a template in namespace std, there's at least some chance that it would work.
I attempted to write a code, and its working with some limitations. Its not stream manipulator as such, as that is simply not possible, as pointed out by others (especially #Jerry).
Here is my code:
struct base
{
mutable std::ostream *_out;
int _value;
base(int value=10) : _value(value) {}
template<typename T>
const base& operator << (const T & data) const
{
*_out << data;
return *this;
}
const base& operator << (const int & data) const
{
switch(_value)
{
case 2:
case 4:
case 8: return print(data);
case 16: *_out << std::hex << data; break;
default: *_out << data;
}
return *this;
}
const base & print(int data) const
{
int digits[CHAR_BIT * sizeof(int)], i = 0;
while(data)
{
digits[i++] = data % _value;
data /= _value;
}
while(i) *_out << digits[--i] ;
return *this;
}
friend const base& operator <<(std::ostream& out, const base& b)
{
b._out = &out;
return b;
}
};
And this is the test code:
int main() {
std::cout << base(2) << 255 <<", " << 54 << ", " << 20<< "\n";
std::cout << base(4) << 255 <<", " << 54 << ", " << 20<< "\n";
std::cout << base(8) << 255 <<", " << 54 << ", " << 20<< "\n";
std::cout << base(16) << 255 <<", " << 54 << ", " << 20<< "\n";
}
Output:
11111111, 110110, 10100
3333, 312, 110
377, 66, 24
ff, 36, 14
Online demo : http://www.ideone.com/BWhW5
Limitations:
The base cannot be changed twice. So this would be an error:
std::cout << base(4) << 879 << base(8) << 9878 ; //error
Other manipulator cannot be used after base is used:
std::cout << base(4) << 879 << std::hex << 9878 ; //error
std::cout << std::hex << 879 << base(8) << 9878 ; //ok
std::endl cannot be used after base is used:
std::cout << base(4) << 879 << std::endl ; //error
//that is why I used "\n" in the test code.
I don't think that syntax is possible for arbitrary streams (using a manipulator, #gigantt linked an answer that shows some alternative non-manipulator solutions). The standard manipulators merely set options that are implemented inside the stream.
OTOH, you could certainly make this syntax work:
std::cout << base(4, 20);
Where base is an object that provides a stream insertion operator (no need to return a temporary string).

Retrieving flags in c++ streams

How can i make use of flags in c++ streams? I know of ios_base::flags(), but when i cout them or compare them, they dont change values even with a new flag. a simple program:
#include <iostream>
using namespace std;
int main(){
cout << cout.flags() << endl;//4098
cout << std::hex << cout.flags() << endl;// 0x1002
return 0;
}
doesnt change the outputted default value (at least for me) of 4098.
my ultimate goal is to compare the stream to flags to see which are set, NOT TO SET NEW ONES. can anyone show me an example of how to do this?
With this code:
cout << std::hex << cout.flags() << endl;
The compiler is allowed to evaluate it in this order:
ios_base::fmtflags f = cout.flags(); // store value before applying std::hex
cout << hex;
cout << f;
cout << endl;
So you're not guaranteed to "see" flag changes this way. However, it is not Undefined Behavior.
The flags are a "bitmask type", which is defined to have certain properties – the actual type used is implementation-defined, but integers, enums, and std::bitsets are possibilities. You can use the normal bit-manipulation operators: ^, &, |, and ~:
bool is_hex(std::ios_base &s) {
return (s.flags() & s.basefield) == s.hex;
}
// is_oct is identical, except with s.oct
// Nothing set in basefield means "determine base from input" for istreams,
// and ostreams use base 10. This makes is_dec harder to write.
bool is_anybase(std::istream &s) {
return (s.flags() & s.basefield) == 0;
}
bool is_dec(std::istream &s) {
std::ios_base::fmtflags base = s.flags() & s.basefield;
return base == dec;
}
bool is_dec(std::ostream &s) {
std::ios_base::fmtflags base = s.flags() & s.basefield;
return (base == dec) || (base == 0);
}
// Purposeful overload ambiguity on std::iostream.
// In 0x, we could write:
bool is_dec(std::iostream &s) = delete;
For an example, this is how std::hex works:
std::ios_base& hex(std::ios_base &s) {
s.setf(s.hex, s.basefield);
return s;
}
Where setf does:
ios_base::fmtflags fmtflags = s.hex; // first parameter
ios_base::fmtflags mask = s.basefield; // second parameter
s.flags((s.flags() & ~mask) | (fmtflags & mask));

How to easily indent output to ofstream?

Is there an easy way to indent the output going to an ofstream object? I have a C++ character array that is null terminate and includes newlines. I'd like to output this to the stream but indent each line with two spaces. Is there an easy way to do this with the stream manipulators like you can change the base for integer output with special directives to the stream or do I have to manually process the array and insert the extra spaces manually at each line break detected?
Seems like the string::right() manipulator is close:
http://www.cplusplus.com/reference/iostream/manipulators/right/
Thanks.
-William
This is the perfect situation to use a facet.
A custom version of the codecvt facet can be imbued onto a stream.
So your usage would look like this:
int main()
{
/* Imbue std::cout before it is used */
std::ios::sync_with_stdio(false);
std::cout.imbue(std::locale(std::locale::classic(), new IndentFacet()));
std::cout << "Line 1\nLine 2\nLine 3\n";
/* You must imbue a file stream before it is opened. */
std::ofstream data;
data.imbue(indentLocale);
data.open("PLOP");
data << "Loki\nUses Locale\nTo do something silly\n";
}
The definition of the facet is slightly complex.
But the whole point is that somebody using the facet does not need to know anything about the formatting. The formatting is applied independent of how the stream is being used.
#include <locale>
#include <algorithm>
#include <iostream>
#include <fstream>
class IndentFacet: public std::codecvt<char,char,std::mbstate_t>
{
public:
explicit IndentFacet(size_t ref = 0): std::codecvt<char,char,std::mbstate_t>(ref) {}
typedef std::codecvt_base::result result;
typedef std::codecvt<char,char,std::mbstate_t> parent;
typedef parent::intern_type intern_type;
typedef parent::extern_type extern_type;
typedef parent::state_type state_type;
int& state(state_type& s) const {return *reinterpret_cast<int*>(&s);}
protected:
virtual result do_out(state_type& tabNeeded,
const intern_type* rStart, const intern_type* rEnd, const intern_type*& rNewStart,
extern_type* wStart, extern_type* wEnd, extern_type*& wNewStart) const
{
result res = std::codecvt_base::noconv;
for(;(rStart < rEnd) && (wStart < wEnd);++rStart,++wStart)
{
// 0 indicates that the last character seen was a newline.
// thus we will print a tab before it. Ignore it the next
// character is also a newline
if ((state(tabNeeded) == 0) && (*rStart != '\n'))
{
res = std::codecvt_base::ok;
state(tabNeeded) = 1;
*wStart = '\t';
++wStart;
if (wStart == wEnd)
{
res = std::codecvt_base::partial;
break;
}
}
// Copy the next character.
*wStart = *rStart;
// If the character copied was a '\n' mark that state
if (*rStart == '\n')
{
state(tabNeeded) = 0;
}
}
if (rStart != rEnd)
{
res = std::codecvt_base::partial;
}
rNewStart = rStart;
wNewStart = wStart;
return res;
}
// Override so the do_out() virtual function is called.
virtual bool do_always_noconv() const throw()
{
return false; // Sometime we add extra tabs
}
};
See: Tom's notes below
Well this is not the answer I'm looking for, but in case there is no such answer, here is a way to do this manually:
void
indentedOutput(ostream &outStream, const char *message, bool &newline)
{
while (char cur = *message) {
if (newline) {
outStream << " ";
newline = false;
}
outStream << cur;
if (cur == '\n') {
newline = true;
}
++message;
}
}
A way to add such feature would be to write a filtering streambuf (i.e. a streambuf which forwards the IO operation to another streambuf but manipulate the data transfered) which add the indentation as part of its filter operation. I gave an example of writing a streambuf here and boost provides a library to help in that.
If your case, the overflow() member would simply test for '\n' and then add the indent just after if needed (exactly what you have done in your indentedOuput function, excepted that newline would be a member of the streambuf). You could probably have a setting to increase or decrease the indent size (perhaps accessible via a manipulator, the manipulator would have to do a dynamic_cast to ensure that the streambuf associated to the stream is of the correct type; there is a mechanism to add user data to stream -- basic_ios::xalloc, iword and pword -- but here we want to act on the streambuf).
I've had good success with Martin's codecvt facet based suggestion, but I had problems using it on std::cout on OSX, since by default this stream uses a basic_streambuf based streambuf which ignores the imbued facet. The following line switches std::cout and friends to use a basic_filebuf based streambuf, which will use the imbued facet.
std::ios::sync_with_stdio(false);
With the associated side effect that the iostream standard stream objects may operate independently of the standard C streams.
Another note is since this facet does not have a static std::locale::id, which meant that calling std::has_facet<IndentFacet> on the locale always returned true. Adding a std::local::id meant that the facet was not used, since basic_filebuf looks for the base class template.
There is no simple way, but a lot has been written about the complex
ways to achieve this. Read this article for a good explanation of
the topic. Here is another article, unfortunately in German. But
its source code should help you.
For example you could write a function which logs a recursive structure. For each level of recursion the indentation is increased:
std::ostream& operator<<(std::ostream& stream, Parameter* rp)
{
stream << "Parameter: " << std::endl;
// Get current indent
int w = format::get_indent(stream);
stream << "Name: " << rp->getName();
// ... log other attributes as well
if ( rp->hasParameters() )
{
stream << "subparameter (" << rp->getNumParameters() << "):\n";
// Change indent for sub-levels in the hierarchy
stream << format::indent(w+4);
// write sub parameters
stream << rp->getParameters();
}
// Now reset indent
stream << format::indent(w);
return stream;
}
I have generalized Loki Astarti's solution to work with arbitrary indentation levels. The solution has a nice, easy to use interface, but the actual implementation is a little fishy. It can be found on github:https://github.com/spacemoose/ostream_indenter
There's a more involved demo in the github repo, but given:
#include "indent_facet.hpp"
/// This probably has to be called once for every program:
// http://stackoverflow.com/questions/26387054/how-can-i-use-stdimbue-to-set-the-locale-for-stdwcout
std::ios_base::sync_with_stdio(false);
// This is the demo code:
std::cout << "I want to push indentation levels:\n" << indent_manip::push
<< "To arbitrary depths\n" << indent_manip::push
<< "and pop them\n" << indent_manip::pop
<< "back down\n" << indent_manip::pop
<< "like this.\n" << indent_manip::pop;
}
It produces the following output:
I want to push indentation levels:
To arbitrary depths
and pop them
back down
like this.
I would appreciate any feedback as to the utility of the code.
Simple whitespace manipulator
struct Whitespace
{
Whitespace(int n)
: n(n)
{
}
int n;
};
std::ostream& operator<<(std::ostream& stream, const Whitespace &ws)
{
for(int i = 0; i < ws.n; i++)
{
stream << " ";
}
return stream;
}