is there a good way to combine stream manipulators? - c++

If I wanted to output a fixed width hex number with 4 digits on a stream, I would need to do something like this:
cout << "0x" << hex << setw(4) << setfill('0') << 0xABC;
which seems a bit long winded. Using a macro helps:
#define HEX(n) "0x" << hex << setw(n) << setfill('0')
cout << HEX(4) << 0xABC;
Is there a better way to combine the manipulators?

Avoid the macros when you can! They hide code, making things hard to debug, don't respect scope, etc.
You can use a simple function as KenE provided. If you want to get all fancy and flexible, then you can write your own manipulator:
#include <iostream>
#include <iomanip>
using namespace std;
ostream& hex4(ostream& out)
{
return out << "0x" << hex << setw(4) << setfill('0');
}
int main()
{
cout << hex4 << 123 << endl;
}
This makes it a little more general. The reason the function above can be used is because operator<< is already overloaded like this: ostream& operator<<(ostream&, ostream& (*funtion_ptr)(ostream&)). endl and some other manipulators are also implemented like this.
If you want to allow the number of digits to be specified at runtime, we can use a class:
#include <iostream>
#include <iomanip>
using namespace std;
struct formatted_hex
{
unsigned int n;
explicit formatted_hex(unsigned int in): n(in) {}
};
ostream& operator<<(ostream& out, const formatted_hex& fh)
{
return out << "0x" << hex << setw(fh.n) << setfill('0');
}
int main()
{
cout << formatted_hex(4) << 123 << endl;
}
If the size can be determined at compile-time, however, might as well just use a function template [thanks to Jon Purdy for this suggestion]:
template <unsigned int N>
ostream& formatted_hex(ostream& out)
{
return out << "0x" << hex << setw(N) << setfill('0');
}
int main()
{
cout << formatted_hex<4> << 123 << endl;
}

Why a macro - can't you use a function instead?
void write4dhex(ostream& strm, int n)
{
strm << "0x" << hex << setw(4) << setfill('0') << n;
}

In C++20 you'll be able to use std::format to make this much less verbose:
std::cout << std::format("0x{:04x}", 0xABC);
Output:
0x0abc
You can also easily reuse the format string by storing it in a constant.
In the meantime you can use the {fmt} library, std::format is based on. {fmt} also provides the print function that makes this even easier and more efficient (godbolt):
fmt::print("0x{:04x}", 0xABC);
Disclaimer: I'm the author of {fmt} and C++20 std::format.

Related

C++ how to cout and write at the same time

After reading this: C++ Writing to file and Console Output at the same time with simple code , I am trying to write a function to handle what I have in the for-loop. But I don't know how to pass a piece of code like this :setw(3) << right << get<0>(*it_party) << setw(9) << "" altogether as an argument into a function so that both cout and file can use it.
The helper function I am trying to write:
void print(std::ostream &os1, std::ostream &os2, const [I don't know what to put in here])
{
os1 << the argument; // cout
os2 << the argument; // file
}
ofstream file;
file.open("test.txt");
for (auto it_party = parties_.begin(); it_party != parties_.end(); ++it_party) {
cout << setw(3) << right << get<0>(*it_party) << setw(9) << "";
file << setw(3) << right << get<0>(*it_party) << setw(9) << "";
cout << setw(7) << left << get<1>(*it_party) << setw(1) << "";
file << setw(7) << left << get<1>(*it_party) << setw(1) << "";
...
...
}
If you want to string outputs together like that, you'll probably find it easier to use some kind of "tee" class:
class Tee {
private:
std::ostream &os1, &os2;
public:
Tee(std::ostream &os1, std::ostream &os2) : os1(os1), os2(os2) { }
template <typename T>
Tee& operator<<(const T &thing) {
os1 << thing;
os2 << thing;
return *this;
}
};
This'll take a template argument, so it won't care whether you're passing right or setw(3). You can use it like:
Tee t(std::cout, std::cout);
t << setw(10) << "right" << " Thing" << setw(9);
You can easily do this using std::stringstream. I don't know what get<>() is but here is a basic example:
#include <string>
#include <iostream>
#include <sstream>
#include <fstream>
void fn(std::string output) {
std::ofstream file("file.txt");
std::cout << output;
file << output;
}
int main() {
std::stringstream buffer;
buffer << "some random text" << std::endl;
fn(buffer.str());
return 0;
}
Unfortunately, you cannot pass all that stuff as only one argument. But there are some advanced techniques, that can help you, such as variadic templates and C++17 fold expressions.
Variadic templates are a feature that allows you, for example, to pass an unknown at compile-time amount of arguments of different types. You can see some examples of such in a standard library, such as std::tuple.
Fold expressions are yet another feature used in combination with the former one. It allows you to write pretty simple variadic-templated code:
template<typename ...Args>
void printer(const Args &... args) {
(std::cout << ... << args) << '\n';
}
Here we see a function, that takes some const & to some arguments (we don't know their count or distinct types), but we have such fancy thing as args, a parameter pack, that represents our arguments, and Args as their types "packed" together;
You can use that to pass arbitrary arguments to your streams:
template<typename ...Args>
void printer(const Args &... args) {
(std::cout << ... << args);
(file << ... << args);
}
There are some other things to improve in this solution, such as perfect forwarding, but these are for further study.

C++ how to avoid trailing zeroes?

If you do
double number;
cout.precision(3)
cout<<number;
for a number like 1.23456 you get 1.234 but if the number is 1.2 you get 1.200. How to get both 1.234 and 1.2 (they are useless zeroes)? Suppose you don't know what number you have to print.
#include <iostream>
#include <iomanip>
using namespace std;
auto main() -> int
{
cout << setprecision( 4 );
cout << 1.23456 << endl; // -> "1.235"
cout << 1.2 << endl; // -> "1.2"
}
It's that simple: it's what you get by default.
C++03 lacked a manipulator for resetting to default formatting after setting fixed or scientific. However, in C++11 the defaultfloat manipulator was introduced. You can use it like this:
#include <iostream> // defaultfloat
#include <iomanip> // setprecision
using namespace std;
#ifdef __GNUC__ // Also check for version number, e.g. 4.8.2 and earlier
namespace std {
inline
auto defaultfloat( ios_base& stream )
-> ios_base&
{ stream.unsetf( ios_base::floatfield ); return stream; }
}
#endif
auto main() -> int
{
cout << "Lots of digits: " << fixed << setprecision( 16 ) << 1.2 << endl;
cout << endl;
cout << "Deault presentation:" << endl;
cout << defaultfloat;
cout << 1.234 << endl;
cout << 1.2 << endl;
}
Did you even try your own example?
Trailing zeroés are NOT printed (by default).
In fact, one usually wants (!) those zeroes (they convey information and they avoid clobbering up the output).
This is achieved by cout << std::fixed.
Unless you have used std::fixed, 1.2 will produce 1.2, NOT 1.200, even with precision higher than 2.
BTW: Precision means all digits, not just those after the dot, hence precision=3 leads to 1.23 - UNLESS you go std::fixed, then only those after the dot are counted.
You might write a manipulator to achieve your formatting:
#include <cmath>
#include <iostream>
template <typename T>
struct DecimalPrecision
{
const T& value;
const unsigned decimals;
DecimalPrecision(const T& value, unsigned decimals)
: value(value), decimals(decimals)
{}
void write(std::ostream& stream) const {
std::ios_base::fmtflags flags = stream.flags();
stream.unsetf(std::ios_base::floatfield);
std::streamsize restore
= stream.precision(std::ceil(std::log10(std::abs(value))) + decimals);
stream << value;
stream.precision(restore);
stream.flags(flags);
}
};
template <typename T>
inline DecimalPrecision<T> decimal_precision(const T& value, unsigned decimals) {
return DecimalPrecision<T>(value, decimals);
}
template <typename T>
inline std::ostream& operator << (std::ostream& stream, const DecimalPrecision<T>& value) {
value.write(stream);
return stream;
}
#include <iomanip>
int main()
{
std::cout << std::setprecision(2);
double values[] = { 12345.6789, 1.23456789, 1.2 };
for(unsigned i = 0; i < sizeof(values)/sizeof(values[0]); ++i)
std::cout
<< i << ": " << values[i] << '\n'
<< " " << decimal_precision(values[i], 2) << '\n';
}

Convert a number from stringstream to string with a set precision

I would like to obtain a number from stringstream and set it to 5 significant figures. How do I do this? So far, this is what I have managed to come up with:
double a = 34.34566535
std::stringstream precisionValue;
precisionValue.precision(6) << a << std::endl;
However, this is not compiling. Thanks.
It doesn't compile because ios_base::precision() returns streamsize (it's an integral type).
You can use stream manipulators:
precisionValue << std::setprecision(6) << a << std::endl;
You'll need to include <iomanip>.
std::stringstream::precision() returns a streamsize, not a reference to the stream itself, which is required if you want to sequence << operators. This should work:
double a = 34.34566535;
std::stringstream precisionValue;
precisionValue.precision(6);
precisionValue << a << std::endl;
The precision member function returns current precision, not a reference to the stringstream, so you cannot chain the calls as you've done in the snippet.
precisionValue.precision(6);
precisionValue << a;
std::cout << precisionValue.str() << std::endl;
Or use the setprecision IO manipulator to chain the calls:
precisionValue << setprecision(6) << a;
std::cout << precisionValue.str() << std::endl;
You can use std::setprecision from header <iomanip>
#include <string>
#include <sstream>
#include <iomanip>
#include <iostream>
int main()
{
double a = 34.34566535;
std::stringstream precisionValue;
precisionValue << std::setprecision(6);
precisionValue << a << std::endl;
std::cout << precisionValue.str();
}

how to format out in c++?

I know how to use printf() to format output of float, for example:
float i = 1;
printf("%.2f", i);
but how to format the output using cout to output 2 digits after "."?
Following will do:
std::cout<<std::fixed<<std::setprecision(2)<<i;
You will also need to include iomanip
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
cout << setprecision(2) << setiosflags(ios::fixed) << 3.141592 << endl;
}
use setprecision().
A red herring is to use std::setprecision on its own:
float f = 3.1415;
std::cout << std::setprecision(2) << f;
However, "precision" is not the same as "number of decimal places", as shown in this example.
Fortunately, and somewhat confusingly, switching the stream to "fixed-point" display changes the meaning of std::setprecision to something more akin to "setDecimalPlaces".
So, you can write this:
float f = 3.1415;
std::cout << std::fixed << std::setprecision(2) << f;
Boost format helps:
std::cout << boost::format("%.2f") % i;
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
double x = 800000.0/81.0;
cout << setiosflags(ios::fixed) << setprecision(2) << x;
return 0;
}
hope this helps.........
#include <iostream>
#include <iomanip>
using namespace std;
int main () {
double f =3.14159;
cout << setprecision (5) << f << endl;
cout << setprecision (9) << f << endl;
cout << fixed;
cout << setprecision (5) << f << endl;
cout << setprecision (9) << f << endl;
return 0;
}
output..
> 3.1416
> 3.14159
> 3.14159
> 3.141590000
cout << ffmt(0, 2) << i;
Where ffmt is defined as:
class ffmt
{
int width;
int precision;
public:
ffmt( int width, int precision )
: width( width )
, precision( precision )
{
}
friend std::ostream& operator<<(
std::ostream& dest,
ffmt const& manip )
{
dest.setf( std::ios_base::fixed, std::ios_base::floatfield );
dest.width( width );
dest.precision( precision );
}
};
You can also extend this to restore format state at the end of the full
expression; it's not too important for floating point, because most of
the time, you'll use the manipulator in front of each output, but a
manipulator which leaves the stream outputting hex is likely to lead to
surprising output later.
As a general rule, except for quicky demo or test programs, you almost
never use the standard manipulators, other that std::setw. For that
matter, in a lot of applications, you'll even avoid things like ffmt,
in favor of specific manipulators for each semantic value you have.

C++: what benefits do string streams offer?

could any one tell me about some practical examples on using string streams in c++, i.e. inputing and outputing to a string stream using stream insertion and stream extraction operators?
You can use string streams to convert anything that implements operator << to a string:
#include <sstream>
template<typename T>
std::string toString(const T& t)
{
std::ostringstream stream;
stream << t;
return stream.str();
}
or even
template <typename U, typename T>
U convert(const T& t)
{
std::stringstream stream;
stream << t;
U u;
stream >> u;
return u;
}
I use them mostly as memory buffers, in creating messages:
if(someVector.size() > MAX_SIZE)
{
ostringstream buffer;
buffer << "Vector should not have " << someVector.size() << " eleements";
throw std::runtime_error(buffer.str());
}
or to construct complex strings:
std::string MyObject::GenerateDumpPath()
{
using namespace std;
std::ostringstream dumpPath;
// add the file name
dumpPath << "\\myobject."
<< setw(3) << setfill('0') << uniqueFileId
<< "." << boost::lexical_cast<std::string>(state)
<< "_" << ymd.year
<< "." << setw(2) << setfill('0') << ymd.month.as_number()
<< "." << ymd.day.as_number()
<< "_" << time.hours()
<< "." << time.minutes()
<< "." << time.seconds()
<< ".xml";
return dumpPath.str();
}
It is useful because it brings all the extensibility of std::streams to using character buffers (ostreams extensibility and locales support, buffer memory management is hidden and so on).
Another example I've seen was the error reporting in gsoap library, using dependency injection: soap_stream_fault takes an ostream& parameter to report error messages in.
If you want you can pass it std::cerr, std::cout or an std::ostringstream implementation (I use it with a std::ostringstream implementation).
They can be used anywhere a normal stream can be used.
So in situations where you were reading from a file you could potentially read from a string stream.
void compile(std::istream& str)
{
CPlusPlusLexer lexer(str);
CPlusPlusParser parser(lexer);
BackEnd backend(parser);
backend.compile();
}
int main()
{
std::fstream file("Plop.cpp");
compile(file);
std::stringstream test("#include <iostream>\n int main() { std::cout << \"H World\n\";}");
compile(test);
}
Besides advantages there is one point to carefully consider if you use gcc 4.3.1. I didn't checked preceding versions of gcc.