custom std::hex manipulator that works for unsigned char - c++

Please consider the following:
unsigned char a(65);
unsigned char z(90);
std::cout << std::hex << a << ", " << z <<std::endl;
Output:
A, Z
But desired output is:
41, 5a
To achieve this I'd like to avoid having to convert values like this, say:
std::cout << std::hex << int(a) << ", " << int(z) <<std::endl;
and instead have some magical manipulator that I can include beforehand:
std::cout << uchar_hex_manip << a << ", " << z << std::endl;
So my question is, how can I define 'uchar_hex_manip' to work as required?
UPDATE: I appreciate all the comments and suggestions so far but I have already said I want to avoid converting the values and no-one seems to have acknowledged that fully. The 'a << ", " << z' I mentioned above is representative of the values to be later streamed in - the actual use case of this in our application is that there is something more complex than that going on where for various reasons it is ideal not to have to shoe-horn in some casts for specific cases.

If you want to print char as hex, you will need to convert it to a an int:
std::cout << std::hex << static_cast<int>('a');
should do the trick.
The reason std::hex doesn't work on char (or unsigned char) is that the stream output operator for char is defined to print the character as the output. There is no modifier to change this behaviour (and although #soon suggests to write your own class - that's a lot of work to avoid a cast).

Related

Is there an easy way to print an int without removing leading zeros? [duplicate]

How can I format my output in C++? In other words, what is the C++ equivalent to the use of printf like this:
printf("%05d", zipCode);
I know I could just use printf in C++, but I would prefer the output operator <<.
Would you just use the following?
std::cout << "ZIP code: " << sprintf("%05d", zipCode) << std::endl;
This will do the trick, at least for non-negative numbers(a) such as the ZIP codes(b) mentioned in your question.
#include <iostream>
#include <iomanip>
using namespace std;
cout << setw(5) << setfill('0') << zipCode << endl;
// or use this if you don't like 'using namespace std;'
std::cout << std::setw(5) << std::setfill('0') << zipCode << std::endl;
The most common IO manipulators that control padding are:
std::setw(width) sets the width of the field.
std::setfill(fillchar) sets the fill character.
std::setiosflags(align) sets the alignment, where align is ios::left or ios::right.
And just on your preference for using <<, I'd strongly suggest you look into the fmt library (see https://github.com/fmtlib/fmt). This has been a great addition to our toolkit for formatting stuff and is much nicer than massively length stream pipelines, allowing you to do things like:
cout << fmt::format("{:05d}", zipCode);
And it's currently being targeted by LEWG toward C++20 as well, meaning it will hopefully be a base part of the language at that point (or almost certainly later if it doesn't quite sneak in).
(a) If you do need to handle negative numbers, you can use std::internal as follows:
cout << internal << setw(5) << setfill('0') << zipCode << endl;
This places the fill character between the sign and the magnitude.
(b) This ("all ZIP codes are non-negative") is an assumption on my part but a reasonably safe one, I'd warrant :-)
Use the setw and setfill calls:
std::cout << std::setw(5) << std::setfill('0') << zipCode << std::endl;
In C++20 you'll be able to do:
std::cout << std::format("{:05}", zipCode);
In the meantime you can use the {fmt} library, std::format is based on.
Disclaimer: I'm the author of {fmt} and C++20 std::format.
cout << setw(4) << setfill('0') << n << endl;
from:
http://www.fredosaurus.com/notes-cpp/io/omanipulators.html
or,
char t[32];
sprintf_s(t, "%05d", 1);
will output 00001 as the OP already wanted to do
Simple answer but it works!
ostream &operator<<(ostream &os, const Clock &c){
// format the output - if single digit, then needs to be padded with a 0
int hours = c.getHour();
// if hour is 1 digit, then pad with a 0, otherwise just print the hour
(hours < 10) ? os << '0' << hours : os << hours;
return os; // return the stream
}
I'm using a ternary operator but it can be translated into an if/else statement as follows
if(c.hour < 10){
os << '0' << hours;
}
else{
os << hours;
}

C++ single quotes syntax

I am learning C++ and just started reading "Programming Principles and Practice" by Bjarne Stroustrup and he uses this code to illustrate a point:
#include "std_lib_facilities.h"
using namespace std;
int main() // C++ programs start by executing the function main
{
char c = 'x';
int i1 = c;
int i2 = 'x';
char c2 = i1;
cout << c << ' << i1 << ' << c2 << '\n';
return 0;
}
I am familiar in general with the difference between double and single quotes in the C++ world, but would someone kindly explain the construction and purpose of the section ' << i1 << '
Thanks
cout << c << ' << i1 << ' << c2 << '\n';
appears to be a typo in the book. I see it in Programming Principles and Practice Using C++ (Second Edition) Second printing. I do not see it listed in the errata.
According to the book, the intended output is
x 120 x
But what happens here is ' << i1 << ' attempts to compress the << i1 << to a multi-byte character and prints out an integer (most likely 540818464-> 0x203C3C20 -> ASCII values of ' ', '<', '<', ' ') because cout doesn't know wide characters. You'd need wcout for that. End result is output something like
x540818464x
and a warning or two from the compiler because while it's valid C++ code, it's almost certainly not what you want to be doing.
The line should most likely read
cout << c << ' ' << i1 << ' ' << c2 << '\n';
which will output the expected x 120 x
In other words, Linker3000, you are not crazy and not misunderstanding the example code.
Anyone know who I should contact to log errata or get a clarification on the off chance there is some top secret sneakiness going way over my head?
Before answering your question, here is a little background on what that is actually doing. Also note that there is a typo in the example, the string constant should have been double quoted:
cout << c << " << i1 << " << c2 << "\n";
In C++, operators can be overloaded so that they mean different things with different functions. In the case of cout, the << operator is overloaded as the "Insertion Operator". Think of it as taking the operand on the right, and inserting it (or sending it) into the operator on the left.
For example,
cout << "Hello World";
This takes the string "Hello World", and sends it to cout for processing.
So what beginners do not get is what something like this means:
cout << "Hello" << " World";
This is doing the same thing, but the operator precedence says to perform the injections from left to right. To make this work, the cout object returns itself as a function return value. Why is this important? Because the above statement is actually two separate operator evaluations:
(cout << "Hello") << " World";
This first injects "Hello" to cout, which outputs it, then continues to evaluate the next inject operator. Because cout returns itself, after the (cout << "Hello") is executed you have the following still to be evaluated:
cout << " World";
This expression injects " World" into the cout object, which then outputs " World", with the net effect being that you see "Hello World" just like the first time.
So in your example, what is it doing?
cout << c << " << i1 << " << c2 << "\n";
This is evaluated left to right as follows:
((((cout << c) << " << i1 << ") << c2) << "\n"); => Outputs value of c
((((cout ) << " << i1 << ") << c2) << "\n"); => Outputs string " << i1 << "
((( cout ) << c2) << "\n"); => Outputs value of c2
(( cout ) << "\n"); => Outputs newline character
( cout ); => No more output
Expression completes and returns the cout object as the expression value.
Assuming c='x' and c2='x', the final output from this expression is the following character string output on a single line:
x << i1 << x
For beginners, all those insertion operators << look a little strange. It is because you are dealing with objects. You could build the string up as a complete formatted object before injecting it into cout, and while that make the cout expression look simpler, we do not do that in C++ because it makes your code more complex and error prone. Note also, there is nothing special about the cout object. If you wanted to output to the standard error stream, you would use cerr instead. If you wanted to output to a file, your would instantiate a stream object that outputs to the desired file. That rest of the code in your example would be the same.
In C, the same thing would be done procedurally using a format string:
printf("%d << i1 << %d\n", i1, c2);
This is allowed in C++ too, because C++ is a superset of C. Many C++ programmers still use this output method, but that is because those programmers learned C first, and may not have fully embraced the object oriented nature of C++
Note that you may also have seen the << operator in the context of mathematical expressions like:
A = A << 8;
In this case, the << operator is the bitwise rotate operation. It has nothing to do with output to cout. It will rotate the bits in A to the left by eight bits.

Switching to cout from printf - Complex format specifier patterns

I have to rewrite a logging system in C++ as part of project requirements (everything has to be C++ instead of C now), and there are a number of ways in which we log things like mathematical data and pointer addresses. It is fairly common to see a log like:
log("%3.4f %d %zp %5.8f", ...);
In C++, using cout instead of printf, it seems a bit more of an involved process to setup such a logging format, eg, taking the following snippet from C++ Primer Plus (Prata):
ios_base::fmtflags initial;
initial = os.setf(ios_base::fixed); // save initial formatting state
os.precision(0);
os.setf(ios::showpoint);
os.precision(1);
os.width(12);
This looks like it will set the width and precision for all floating point items in the argument list, and won't allow me to have different values for different variables.
Can cout even generate such a string in a simple manner with just one line of code, or should I use sprintf to prepare my strings and then feed them to cout?
Thanks!
Question the requirements!
printf works fine in C++, proper use of compiler warnings prevent type inconsistencies. The C++ formatting alternative is too complicated and error prone: it is so easy to leave the stream formatting in a different state than upon entry.
If you really need to use cout, use snprintf() to format the log entry and shift the formatted string to cout.
Can cout even generate such a string in a simple manner with just one
line of code, or should I use sprintf to prepare my strings and then
feed them to cout?
I agree that sprintf() is not C++. It merely provides some manner of backward compatibility ... i.e. it has been provided specifically so that you can post-pone the conversion (of c to c++) and that technical debt to later in your schedule.
Here is a code sample from when I 'fixed' a log to be C++. (I left in the sprintf() to help document the new C++ code.)
//retVal = ::sprintf(buff1, "%08llx %2d:%02d:%02d, %05llu.%03llu: ",
// a_pid, hr, min, sec, (ms_of_day / 1000), (rt_ms % 1000));
// use stringstream formatting, not sprintf
buff1 << std::dec << std::setfill('0') << std::setw(8) << a_pid << " "
<< std::setfill('0') << std::setw(2) << hr << ":"
<< std::setfill('0') << std::setw(2) << min << ":"
<< std::setfill('0') << std::setw(2) << sec << ", "
<< std::setfill('0') << std::setw(5) << (ms_of_day / 1000)
<< "."
<< std::setfill('0') << std::setw(3) << (ms_of_day % 1000)
<< ": ";
I only had to do this once.
In a lot of ways, I do not miss the 'unsafe-type' style of sprintf.
If there is something special you do often, you might also consider creating something like the following.
std::string ssprintf0x08x(std::string label, void* ptr)
{
std::stringstream ss;
ss << label << "0x"
<< std::hex << std::internal << std::setw(8)
<< std::setfill('0')
<< reinterpret_cast<uint64_t>(ptr);
return (ss.str());
}
I only had to implement this one time.
Answer to question:
Can cout even generate such a string in a simple manner with just one
line of code?
Yes. Of course.
C++ stream output has a learning curve, but it leads you to a type-safe approach for text output.
And, perhaps you are realizing, one line of code can be quite long.

std::cout gives different output from qDebug

I am using Qt, and I have an unsigned char *bytePointer and want to print out a number-value of the current byte. Below is my code, which is meant to give the int-value and the hex-value of the continuous bytes that I receive from a machine attached to the computer:
int byteHex=0;
byteHex = (int)*bytePointer;
qDebug << "\n int: " //this is the main issue here.
<< *bytePointer;
std::cout << " (hex: "
<< std::hex
<< byteHex
<< ")\n";
}
This gives perfect results, and I get actual numbers, however this code is going into an API and I don't want to use Qt-only functions, such as qDebug. So when I try this:
int byteHex=0;
byteHex = (int)*bytePointer;
std::cout << "\n int: " //I changed qDebug to std::cout
<< *bytePointer;
std::cout << " (hex: "
<< std::hex
<< byteHex
<< ")\n";
}
The output does give the hex-values perfectly, however the int-values return symbols (like ☺, └, §, to list a few).
My question is: How do I get std::cout to give the same output as qDebug?
EDIT: for some reason the symbols only occur with a certain Qt setting. I have no idea why it happened but it's fixed now.
As others pointed out in comment, you change the outputting to hex, but you do not actually set it back here:
std::cout << " (hex: "
<< std::hex
<< byteHex
<< ")\n";
You will need to apply this afterwards:
std::cout << std::dec;
Standard output streams will output any character type as a character, not a numeric value. To output the numeric value, convert to a non-character integer type:
std::cout << int(*bytePointer);

C++ const casting

I am trying to print the value of a const but it is not working. I am making a return to C++ after years so I know casting is a possible solution but I can't get that working either.
The code is as follows:
//the number of blanks surrounding the greeting
const int pad = 0;
//the number of rows and columns to write
const int rows = pad * 2 + 3;
const string::size_type cols = greeting.size() + pad * 2 + 2;
cout << endl << "Rows : " + rows;
I am trying to print the value of 'rows' without success.
You want:
cout << endl << "Rows : " << rows;
Note this has nothing to do with const - C++ does not allow you to concatenate strings and numbers with the + operator. What you were actually doing was that mysterious thing called pointer arithmetic.
You're almost there:
cout << endl << "Rows : " << rows;
The error is because "Rows : " is a string literal, thus is a constant, and generally speaking is not modified as you may think.
Going slightly further, you likely used + (colloquially used as a concatenation operation) assuming you needed to build a string to give to the output stream. Instead operator << returns the output stream when it is done, allowing chaining.
// It is almost as if you did:
(((cout << endl) << "Rows : ") << rows)
I think you want:
std::cout << std::endl << "Rows : " << rows << std::endl;
I make this mistake all the time as I also work with java a lot.
As others have pointed out, you need
std::cout << std::endl << "Rows : " << rows << std::endl;
The reason (or one of the reasons) is that "Rows : " is a char* and the + operator for char*s doesn't concatenate strings, like the one for std::string and strings in languages like Java and Python.