iomanip / fixed width persistence - c++

Why does
#include <iostream>
#include <iomanip>
int main()
{
std::cout << std::fixed << std::setw(4) << std::setprecision(0);
std::cout << 4;
std::cout << 4;
}
print
" 44
(ignore the quote, it's just to get the formatting right)
and not
" 4 4
?
I thought that the iostream 'modifiers' persistent on the stream until they are explicitly changed/reset. I have a bunch of numbers I need to print with a certain prefix so that all fields have equal width; should I re-apply my modifiers every time I print one? Doesn't seem very efficient.

Unfortunately you've wandered into one of the areas of the standard that's a little archaic and seemingly without any overarching design goals.
This is undoubtedly historic as the iostreams library AFAIAA, was not originally part of the STL which is what became the standard library.
It's worth reading the notes on all std::ios_base members and the associated manipulators.
For example:
http://en.cppreference.com/w/cpp/io/ios_base/width
Some I/O functions call width(0) before returning, see std::setw (this results in this field having effect on the next I/O function only, and not on any subsequent I/O)
The exact effects this modifier has on the input and output vary between the individual I/O functions and are described at each operator<< and operator>> overload page individually.
Anticipating:
But that's just <insert expletive>!!!
A: yup.

Related

Empty file check on std::ofstream

I've been using std::ofstream for writing purposes quite a bit. I open the file, do some operations based on certain conditions and close it.
Let's say that later I want to check if anything is really written into the file or not. There is not is_emtpy() kind of simple check available with std::ofstream.
One way I thought is of using the stat way which is independent of std::ofstream.
Wonder how do everyone else do it?
Standard output streams provide a tellp() method which can be used to determine the current write position. The type and meaning of the return value is implementation-defined, but for it to be useful, it must return distinct values.
#include <iostream>
#include <fstream>
int main()
{
std::ofstream out{"/tmp/test"};
auto const empty_pos = out.tellp();
std::clog.setf(std::ios_base::boolalpha);
std::clog << "At start: " << (out.tellp() != empty_pos) << '\n';
out << 'c';
std::clog << "After writing 1 char: " << (out.tellp() != empty_pos) << '\n';
}
In principle, empty_pos may be different for each stream, so a truly portable program will take that into account.
Note also that this doesn't necessarily mean that the output is visible to other programs - use std::flush if that's important.

Why does cout return smanip?

Could anyone explain me the declaration of the setw manipulator? I was completely blown off trying to understand it.! The declaration of the setw in iomanip is as follows
smanip setw(int)
now what is smanip? what happens when we give std::cout << setw(10) << "Hai" [ i want to know how the output is actually affected by setw, in other words the actions happening under the hood)
smanip is an implementation-defined type. The library can define or typedef it to anything it likes, as long as the job gets done.
In practice, it will be some kind of structure representing (a) the manipulation to be performed, and (b) the argument 10 to be used in this manipulation. It might also have a function to perform the manipulation, or it might not, depending how the implementation has defined operator<<(ostream &, smanip), or some similar overload to catch the necessary operand types. I haven't checked my implementation to find out.
As for how the output is affected: my_stream << setw(10) is defined to have the same effect on the stream as calling my_stream.width(10). So the operator<< overload will ensure that happens in some implementation-specific way. The operator overload for non-parameterized stream manipulators is defined specifically to call the manipulator, but with smanip there's a little more freedom for implementations.
setw(int) by itself doesn't modify anything. It simply returns a stream manipulator (smanip) that can be used to modify the stream's behaviour.
// setw example
#include <iostream>
#include <iomanip>
using namespace std;
int main () {
cout << setw (10);
cout << 77 << endl;
return 0;
}

Transparently manipulating strings inserted into an ostream

I'd like to provide an std::ostream that may or may not, from the user's point of view, encrypt its contents.
Imagine some random function that uses an std::ostream&:
void write_stuff( std::ostream& stream ) {
os << "stuff";
}
Whether stuff is output in cleartext or is encrypted is dependent on how the stream argument was initialized.
I'm thinking about inheriting from std::basic_streambuf, but I'm not sure it's the best way to go. I think the ideal scenario is some sort of filter object which is run before the contents are actually output. That way it'd be easy to chain operations, e.g. encrypting and then hex-encoding, which is a benefit that making my own basic_streambuf does not seem to give (not easily at least).
Any advices?
Thanks.
UPDATE: I followed the strategy laid out by the accepted answer. I found this article on writing a custom streambuf which performs XOR obfuscation to be extremely helpful as a starting point.
A streambuf can be implemented in terms of another arbitrary streambuf that's either passed in as an argument to the constructor or set with a special member function. And that allows you to stack streambuf implementations like you were thinking of.
You could even make a manipulator that uses the ostream's rdbuf function to get the current streambuf, call a function on your streambuf that sets the 'stacked' streambuf, and then calls rdbuf again to replace the ostream's streambuf with your own.
aes_ctr_streambuf encrypter(key);
zlib_streambuf compressor;
::std::cout << stack_streambuf(encrypter) << stack_streambuf(compressor);
It is hard to describe in short what you have to do in order to create an I/O stream for the new source or sink. Luckily, Jonathan Turkanis and CodeRage, LLC have created very nice building blocks with exceptional documentation that can help you save hundreds of hours of research and development of new streams. The library is called Boost.Iostreams.
The second example in documentation exactly shows how to solve your problem.
Also, note that they already have an output stream with zip compression. So maybe you don't even need to write a single line of code.
Good luck!
I'm not sure that what I'm about to suggest is exactly what you need (and its too complicated to be a comment), but have you ever heard of the stream manipulators ?
#include <iostream>
#include <iomanip>
int main(int, char**)
{
int a = 10;
std::cout << "a: " << a << std::endl; //outputs: "a: 10"
std::cout << "a: " << std::hex << a << std::endl; //outputs: "a: a"
std::cout << "a: " << std::dec << a << std::endl; //outputs: "a: 10"
return EXIT_SUCCESS;
}
You may indeed use a similar pattern (this matches what you actually call a "filter" object) to somehow change the state of your custom stream object.

C++ : convert date/time string to tm struct

Consider this somewhat of a follow up to this question. Essentially, the C++ date/time formatting facilities seem to be hopelessly broken - so much so that in order to do something as simple as convert a date/time string into an object, you really have to resort to either Boost.Datetime or good old C strftime/strptime facilities.
The problem is that neither of these solutions work directly with the C++ locale settings imbued onto a particular iostream object. The C facilities use the global C/POSIX locale settings, whereas the I/O facilities in Boost.Datetime seem to bypass iostream locale settings entirely by allowing the user to directly set the names of months, weekdays, etc., regardless of locale.
So, I wanted something that would respect the locale settings imbued onto a particular I/O stream that would allow me to convert a string into a struct tm. It seemed easy enough, but I ran into obstacles around every corner. At first, I noticed that some implementations of the STL provide a non-standard std::time_get::get function, so I decided to implement something similar. Basically, I would simply iterate over the format string and whenever I hit a format flag, I would use one of the time_get facilities (like get_monthname, get_weekday, get_year, etc.) to convert the input string into a struct tm. This seems easy enough, except each one of these functions requires an exact iterator range. You can't convert "Monday,", it has to be "Monday" exactly, or the conversion fails. Since the iterators have to be istreambuf_iterator, you can't simply scan ahead, because each increment changes the get position in the stream buffer. So, basically you have to first iterate over the stream, copying each character into another streambuffer, and then when you hit a delimiter (like a space or a comma), use the second streambuffer with the time_get facilities. It's literally as if the C++ designers went out of their way to make this as annoying as possible.
So, is there an easier solution? What do most C++ programmers do when they need to convert a date/time string to an object? Do we just have to use the C facilities, and lose the advantages that come along with different locale settings imbued on different iostream objects?
Boost uses the standard locale(s) by default; you don't have to bypass anything:
#include "boost/date_time/gregorian/gregorian.hpp"
#include <iostream>
#include <sstream>
#include <ctime>
int main(){
using namespace boost::gregorian;
std::locale::global(std::locale(""));
std::locale german("German_Germany");
std::locale french("French_France");
date d1(day_clock::local_day());
date d2;
std::stringstream ss("2002-May-01");
std::cout << "Mine: " << d1 << " | ";
ss >> d2;
std::cout << d2 << '\n';
std::cout.imbue(german);
std::cout << "Germany: " << d1 << " | ";
ss.imbue(german);
ss << "2002-Mai-01";
ss >> d2;
std::cout << d2 << '\n';
std::cout.imbue(french);
std::cout << "France: " << d1 << " | " << d2 << '\n';
std::tm t = to_tm(d1);
std::cout << "tm: " << asctime(&t);
}
(Those locale names are specific to Windows, of course.) Output:
Mine: 2010-Oct-28 | 2002-May-01
Germany: 2010-Okt-28 | 2002-Mai-01
France: 2010-oct.-28 | 2002-mai-01
tm: Thu Oct 28 00:00:00 2010
Why not use the C library? It's almost certainly available in your implementation, and it's well debugged and tested.
If it's lacking some feature, surely it's easier to make wrapper function which does the timezone work you desire.
I always try to use locale independent strings to serialize data. Makes life a lot easier.

Table layout using std::cout

How do I format my output in C++ streams to print fixed width left-aligned tables? Something like
printf("%-14.3f%-14.3f\n", 12345.12345, 12345.12345);
poducing
12345.123 12345.123
Include the standard header <iomanip> and go crazy. Specifically, the setw manipulator sets the output width. setfill sets the filling character.
std::cout << std::setiosflags(std::ios::fixed)
<< std::setprecision(3)
<< std::setw(18)
<< std::left
<< 12345.123;
You may also consider more friendly functionality provided by one of these:
Boost.Format (powerful, but very heavy, more time and memory allocations than other mentioned)
Loki.SafeFormat
FastFormat (relatively new, but blazing fast library, also type-safe unlike the others)
Writing from memory, but should be something along these lines:
// Dumb streams:
printf("%-14.3f%-14.3f\n", 12345.12345, 12345.12345);
// For IOStreams you've got example in the other answers
// Boost Format supports various flavours of formatting, for example:
std::cout << boost::format("%-14.3f%-14.3f\n") % a % b;
std::cout << boost::format("%1$-14.3f%2$-14.3f\n") % a % b;
// To gain somewhat on the performance you can store the formatters:
const boost::format foo("%1$-14.3f%2$-14.3f\n");
std::cout << boost::format(foo) % a % b;
// For the Loki::Printf it's also similar:
Loki::Printf("%-14.3f%-14.3f\n")(a)(b);
// And finally FastFormat.Format (don't know the syntax for decimal places)
fastformat::fmtln(std::cout, "{0,14,,<}{1,14,,>}", a, b);
Also, if you plan to stick with any of these formatting libraries, examine thoroughly their limitations in context of expressibility, portability (and other library dependency), efficiency, support of internationalisation, type-safety, etc.
You want to use stream manipulators:
http://www.deitel.com/articles/cplusplus_tutorials/20060218/index.html