I did my googling for this thing, but haven't found the answer.
I want to find analogue for output formatting in plain C. To be more specific, something which works similar to printf(%.3x)
Probably, it could be done using manipulators. However, the code
cout << showbase << setfill('0') << setw(5) << hex << 19 << endl;
gives me 00x13 instead of desired 0x013.
P.S. Sorry, I don't have the Boost library, so this is not a solution..
Utilizing internal:
cout << showbase << setw(5) << setfill('0') << internal << hex << 19 << endl;
cout << "0x" << setfill('0') << setw(3) << hex << 19 << endl;
Note that setfill and hex alter the state of the stream for subsequent output as well, unlke setw which just affects the next output.
char buffer[40];
snprintf(buffer, 40, "%.3x", 19);
std::cout << buffer;
Related
If I write code like this:
int a = 123456;
cout << setw(20) << setiosflags(ios::right) << a << endl;
cout << setiosflags(ios::left) << setw(20) << a << '*' << endl;
On the 3rd line, I set the alignment as left align, so my expected output is
123456
123456 *
but the REAL output is
123456
123456*
Why did that happen?
The IDE I use is DevCpp.
std::setiosflags() sets new flags without clearing any existing flags. So on the 3rd line, you are enabling the ios::left flag without disabling the ios::right flag. It does not make sense to have both flags enabled at the same time, and it seems the stream prefers the ios::right flag if it is enabled.
Use std::left and std::right instead. They reset the ios::internal, ios::left, and ios::right flags before setting the new alignment.
int a = 123456;
cout << setw(20) << right << a << endl;
cout << left << setw(20) << a << '*' << endl;
Live demo
If you remove the line with setiosflags(ios::right), it works as expected, so it seems all common compilers evaluate right before left and short circuit the program flow. Try either manually unsetting ios::right, or better yet, just use std::left like so:
cout << left << setw(20) << a << '\n';
This, as so many standard library functions, takes care of pesky details.
int a = 123456;
cout.setf(ios::right, ios::adjustfield);
cout << setw(20) << a << endl;
cout.setf(ios::left, ios::adjustfield);
cout << setw(20) << a << '*' << endl;
If I recall, you need to reset the alignment.
The setiosflags sets format flag for the output stream (here it's cout), not for this sentence only. Since the ios::right has priority over ios::left, the second line will be aligned right. So you need to clear the previous format flag and then set the new one.
int a = 123456;
cout << setw(20) << setiosflags(ios::right) << a << endl;
cout << resetiosflags(ios::right) << setiosflags(ios::left) << setw(20) << a << '*' << endl;
But the simplest way is to use std::left and std::right
int a = 123456;
cout << setw(20) << right << a << endl;
cout << left << setw(20) << a << '*' << endl;
My teacher says that for the assignment we are not allowed to manually print the 0x before the hex number, we have to make the system do it.
Currently my code looks like this:
cout << "Hex" << setw(12) << hex << static_cast<int>(letter) << setw(12) << hex
<< number << setw(12) << hex << static_cast<int> (symbol) << endl;
It prints the correct hex value but without the 0x.
Additionally, for octal numbers, I have to again, make the system print a 0 before the number (not manually. My code prints correct values, but without the preceding 0:
cout << "Octal" << setw(12) << setbase(8) << static_cast<int>(letter) << setw(12) << setbase(8)
<< number << setw(12) << setbase(8) << static_cast<int>(symbol) << endl;
Use std::showbase:
std::cout << std::hex << std::showbase << 1234567890;
I have the following code
cout << setfill('0') << setw(4) << hex << 100 << 100 << std::endl;
The output is:
006464
If I want to let every number with width 4, I have to use
out << setfill('0') << setw(4) << hex << 100 << sew(4) << 100 << std::endl;
But if I want to print every number with hex and setfill('0'), I only need to set setfill('0') and std::hex once.
Does c++ design this on purpose? what is its intention?
Yes it is on purpose. The stream operations are internally peppered with resets of the field width, specified by the standard. I think there's no good answer as to why.
Not sure how else to put that, but I'll start off with a code snippet and output:
uint32_t expires;
cout << "Expiration bytes: " << setfill('0') << hex
<< setw(2) << (unsigned short)rec[keyLen+4]
<< setw(2) << (unsigned short)rec[keyLen+5]
<< setw(2) << (unsigned short)rec[keyLen+6]
<< setw(2) << (unsigned short)rec[keyLen+7] << endl;
expires = ntohl(*(uint32_t*)&rec[keyLen+4]);
cout << "Expiration: " << (long)expires << endl;
cout << "Hex: " << hex << expires << endl;
Outputs:
Expiration bytes: 00000258
Expiration: 258
Hex: 258
I can confirm from other parts of the program that examining and outputting the hex representation of bytes works as expected, and that those are indeed the bytes in the byte stream (sent from another application).
Now, I would be able to understand a bit better if expiration just held some nonsense, because that would mean there's some egregious error (probably involving pointers). But this... this is clearly just spitting out the hex value as if it were a decimal, and that's plain wrong.
To make matters more confusing, this works at another point in the program:
fullSize = ntohs(*(uint16_t*)&buff[0]);
With a byte value of 0x0114, fullSize will contain the value 276.
So the question is, what the heck is going on here? How is it possible for an int to be wrong?
hex is sticky, so unless you reset it, cout will continue to output things in hex.
You can reset it by issuing sending std::dec to the stream. Alternatively you could build a more advanced mechanism that would store the original state and restore it afterwords.
cout << "Expiration: " << dec << (long)expires << endl; will output decimal, otherwise the last setting (hex or dec) will still be in effect.
Since you never switch cout back to decimal output, all of your outputs are in hex, even the output of cout << "Expiration: " << (long)expires << endl;.
This question already has answers here:
Restore the state of std::cout after manipulating it
(9 answers)
Closed 4 years ago.
I've got a line of code that sets the fill value to a '-' character in my output, but need to reset the setfill flag to its default whitespace character. How do I do that?
cout << setw(14) << " CHARGE/ROOM" << endl;
cout << setfill('-') << setw(11) << '-' << " " << setw(15) << '-' << " " << setw(11) << '-' << endl;
I thought this might work:
cout.unsetf(ios::manipulatorname) // Howerver I dont see a manipulator called setfill
Am I on the wrong track?
Have a look at the Boost.IO_State_Savers, providing RAII-style scope guards for the flags of an iostream.
Example:
#include <boost/io/ios_state.hpp>
{
boost::io::ios_all_saver guard(cout); // Saves current flags and format
cout << setw(14) << " CHARGE/ROOM" << endl;
cout << setfill('-') << setw(11) << '-' << " " << setw(15) << '-' << " " << setw(11) << '-' << endl;
// dtor of guard here restores flags and formats
}
More specialized guards (for only fill, or width, or precision, etc... are also in the library. See the docs for details.
You can use copyfmt to save cout's initial formatting. Once finished with formatted output you can use it again to restore the default settings (including fill character).
{
// save default formatting
ios init(NULL);
init.copyfmt(cout);
// change formatting...
cout << setfill('-') << setw(11) << '-' << " ";
cout << setw(15) << '-' << " ";
cout << setw(11) << '-' << endl;
// restore default formatting
cout.copyfmt(init);
}
You can use the ios::fill() function to set and restore the fill character instead.
http://www.cplusplus.com/reference/iostream/ios/fill/
#include <iostream>
using namespace std;
int main () {
char prev;
cout.width (10);
cout << 40 << endl;
prev = cout.fill ('x');
cout.width (10);
cout << 40 << endl;
cout.fill(prev);
return 0;
}
You can manually change the setfill flag to whatever you need it to be:
float number = 4.5;
cout << setfill('-');
cout << setw(11) << number << endl; // --------4.5
cout << setfill(' ');
cout << setw(11) << number << endl; // 4.5
The null character will reset it back to the original state:
setfill('\0')