inconsistent behavior of <iomanip> - c++

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.

Related

How do I make the system print 0x before the hex number & 0 before the octal number?

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;

C++ Beginner: How do I prevent the text in my table from pushing any text to the right of it?

I am working on a very basic program for my Fundamentals I class and I have everything 98% working as intended.
This program takes the names of three grades, averages them, and outputs them into a table, but since assignmentName[] is on the same line of code as grade[], it pushes grade[] to the right determining on how many characters the user inputted.
Screenshot of the problem
Here is the code I currently have written for the table:
cout << "___________________________\n";
cout << name << "'s Grade Chart\n";
cout << "---------------------------\n";
cout << setprecision(1) << fixed;
cout << "Grade for " << assignmentName[0] << setw(8) << grade[0] << endl;
cout << "Grade for " << assignmentName[1] << setw(8) << grade[1] << endl;
cout << "Grade for " << assignmentName[2] << setw(8) << grade[2] << endl;
cout << "\nYour average grade between those three assignments is: " << setw(1) << avg << endl;`
I commented, "Place another setw(N) where N is a bit bigger than the largest assignmentName before each << assignmentName."
But on second thought it's bit more fun than that, so I figure a real answer is in order.
First, some reading materials:
Documentation on std::left and std::right
Documentation on std::max
And now on with the show!
First we need to know how big the largest assignment name is.
size_t max = 0;
for (const string & assn: assignmentName)
{
max = std::max(max, assn.length());
// You may need
//max = std::max(max, strlen(assn));
// if you've been forced to resort to barbarism and c-style strings
}
max++; // one extra character just in case we get a really long grade.
Sometimes this can get a lot neater. For example std::max_element can eliminate the need for the loop we used to get the maximum assignment name length. In this case we're looking for the size of the string, not the lexical order of the string, so I think the loop and std::max is a bit easier on the brain.
And now to format, we print the names left-justified and the grades right justified, with the names padded max characters and the grades 8 characters.
cout << "Grade for " << std::left << setw(max) << assignmentName[0]
<< std::right << setw(8) << grade[0] << '\n'
<< "Grade for " << std::left << setw(max) << assignmentName[1]
<< std::right << setw(8) << grade[1] << '\n'
<< "Grade for " << std::left << setw(max) << assignmentName[2]
<< std::right << setw(8) << grade[2] << '\n';
Note it's now one big cout. This was done mostly for demonstration purposes and because I think it looks better. It doesn't really save you much, if anything, in processing time. What does save time is the lack of endls. endl is actually a very expensive operation because not only does it end a line, but it also flushes. It forces whatever has been buffered in the stream out to the underlying media, the console in this case. Computers are at their best when they can avoid actually going out of the computer until they really have to. Drawing to the screen is way more expensive than writing to RAM or a cache, so don't do it until you have to.
Instead of writing:
"Grade for " << assignmentName[x] << setw[y] << grade(z)
Write:
"Grade for " << setw[a] << assignmentName[x] << setw[y] << grade(z)
Where a is greater than x in each case.
Maybe that should fix it.
Your a should be something like 10 or 15 or something. I hope it works after that. Try it.

Integer output formatting. what is the analogue of printf(%.3x)?

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;

Why does this `int` have the wrong value?

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;.

Cannot display in hexadecimal

unsigned int i = 0x02081;
cout << std::hex << i;
This displays 2081 when compiled with VS2010 but I think it should display 0x02081. Am I right, and if so, how can this be fixed?
By default the base is not printed:
cout << std::hex << std::showbase << i;
The easiest solution, of course, is:
cout << "0x" << std::hex << i;
Leading zeroes can vary in amount because they don't matter. You can choose any amount you like.
I think it should display 0x02081. Am
I right
No, you're not. It will display the value in hex, which is 2081. The 0x isn't part of the number, per se, it's just a notational convenience. The leading zero is also not a part of the number.
If you want the exact output you said you expected, you can do this:
cout << std::hex << std::showbase << std::setw(5) << std::setfill('0') << i;
It should display the value of i as a hexadecimal number - and does so. The prefix 0x is just something some programming languages use to indicate that a literal should be considered hexadecimal.
cout << "0x" << std::hex << i;
As Let_Me_Be points out: "0x" << std::hex could be replaced with std::hex << std::showbase if you want automatic printing of 0x/0/nothing for hex/octal/decimal.