Printing chars as Integers - c++

I want to control whether my ostream outputting of chars and unsigned char's via << writes them as characters or integers. I can't find such an option in the standard library. For now I have reverted to using multiple overloads on a set of alternative print functions
ostream& show(ostream& os, char s) { return os << static_cast<int>(s); }
ostream& show(ostream& os, unsigned char s) { return os << static_cast<int>(s); }
Is there a better way?

No, there isn't a better way. A better way would take the form of a custom stream manipulator, like std::hex. Then you could turn your integer printing off and on without having to specify it for each number. But custom manipulators operate on the stream itself, and there aren't any format flags to do what you want. I suppose you could write your own stream, but that's way more work than you're doing now.
Honestly, your best bet is to see if your text editor has functions for making static_cast<int> easier to type. I assume you'd otherwise type it a lot or you wouldn't be asking. That way someone who reads your code knows exactly what you mean (i.e., printing a char as an integer) without having to look up the definition of a custom function.

Just an update to an old post. The actual trick is using '+'. Eg:
template <typename T>
void my_super_function(T x)
{
// ...
std::cout << +x << '\n'; // promotes x to a type printable as a number, regardless of type
// ...
}
In C++11 you could do:
template <typename T>
auto promote_to_printable_integer_type(T i) -> decltype(+i)
{
return +i;
}
Credit: How can I print a char as a number? How can I print a char* so the output shows the pointer’s numeric value?

I have a suggestion based on the technique used in how do I print an unsigned char as hex in c++ using ostream?.
template <typename Char>
struct Formatter
{
Char c;
Formatter(Char _c) : c(_c) { }
bool PrintAsNumber() const
{
// implement your condition here
}
};
template <typename Char>
std::ostream& operator<<(std::ostream& o, const Formatter<Char>& _fmt)
{
if (_fmt.PrintAsNumber())
return (o << static_cast<int>(_fmt.c));
else
return (o << _fmt.c);
}
template <typename Char>
Formatter<Char> fmt(Char _c)
{
return Formatter<Char>(_c);
}
void Test()
{
char a = 66;
std::cout << fmt(a) << std::endl;
}

In C++20 you'll be able to use std::format to do this:
unsigned char uc = 42;
std::cout << std::format("{:d}", uc); // format uc as integer 42 (the default)
std::cout << std::format("{:c}", uc); // format uc as char '*' (assuming ASCII)
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.

Related

Making boost::spirit::hold_any accept vectors

According to its author #hkaiser, here boost::spirit::hold_any is a more performant alternative to boost::any and can, for the most part, be used as a drop-in replacement for the latter. I'm interested in it since it purports to allow for easy output streaming, a feature that boost::any lacks.
While I'm able to input simple types like int into hold_any, I can't seem to get it to hold a container such as std::vector<int> for example. Here'e the code
#include <iostream>
#include <boost/spirit/home/support/detail/hold_any.hpp> // v1.79
#include <vector>
using any = boost::spirit::hold_any;
int main() {
int a1 = 1;
any v1(a1); // OK
std::cout << v1 << std::endl; // OK
std::vector<int> w2 = {5,6};
any v2(w2); // compilation error - invalid operands to binary expression ('std::basic_istream<char>' and 'std::vector<int>')
std::cout << v2 << std::endl;
}
which fails to compile with
hold_any.hpp:155:23: error: invalid operands to binary expression ('std::basic_istream<char>' and 'std::vector<int>')
i >> *static_cast<T*>(*obj);
Presumably, the std::vector<int> needs to be made istream streamable though I'm not sure how to proceed. How does one make this work?
Firstly, that advice is 12 years old. Since then std::any was even standardized. I would not assume that hold_any is still the better choice (on the contrary).
Also, note that the answer you implied contains the exact explanation:
This class has two differences if compared to boost::any:
it utilizes the small object optimization idiom and a couple of other optimization tricks, making spirit::hold_any smaller and faster than boost::any
it has the streaming operators (operator<<() and operator>>()) defined, allowing to input and output a spirit::hold_any seemlessly.
(emphasis mine)
Incidentally, the whole question was about streaming any in the first place, so the answer was on-point there.
The code further drives home the assumption:
// these functions have been added in the assumption that the embedded
// type has a corresponding operator defined, which is completely safe
// because spirit::hold_any is used only in contexts where these operators
// do exist
template <typename Char_>
friend inline std::basic_istream<Char_>&
operator>> (std::basic_istream<Char_>& i, basic_hold_any<Char_>& obj)
{
return obj.table->stream_in(i, &obj.object);
}
template <typename Char_>
friend inline std::basic_ostream<Char_>&
operator<< (std::basic_ostream<Char_>& o, basic_hold_any<Char_> const& obj)
{
return obj.table->stream_out(o, &obj.object);
}
So, indeed that explains the requirement. It's a bit unfortunate that the implementation is not SFINAE-ed so that you'd only run into the limitation if you used the stream_in/stream_out operations, but here we are.
I was able to make the above code work by making a generic vector std::vector<T> both output and input streamable.
#include <iostream>
#include <boost/spirit/home/support/detail/hold_any.hpp>
#include <vector>
using any = boost::spirit::hold_any;
namespace std {
// input stream
template<typename T>
std::istream& operator >> ( std::istream& ins, std::vector<T>& p ) {
size_t sz;
ins >> sz;
for ( size_t i = 0; i < sz; ++i ) {
T tmp;
ins >> tmp;
p.push_back( tmp );
}
return ins;
}
// output stream
template<typename T>
std::ostream& operator << ( std::ostream& outs, const std::vector<T>& p ) {
outs << "[";
for ( size_t i = 0; i < p.size(); ++i ) {
outs << p[i];
if ( i != p.size() - 1 )
outs << " ";
else
outs << "]";
}
return outs;
}
}
I'd appreciate any comments on how to make the above more performant. boost::iostreams perhaps?

iostream equivalent to snprintf(NULL, 0, format_string, args...)

I want to find the number of characters that a stream formatting operation would produce without allocating memory from the heap. In C, it can be done with
int nchars = snprintf(NULL, 0, format_string, args...);
How can it be done within the ostream framework in C++?
An implementation with std::ostringstream may allocate memory from the heap:
template <class T>
int find_nchar(const T& value) {
std::ostringstream os; // may allocate memory from the heap
os << value;
return os.str().size(); // may allocate memory from the heap
}
I think I need to make a custom ostream class to achieve this. The custom ostream should respect all the formatting flags one can set for the normal std::ostream.
I am searching for a solution that only uses the C++ standard library, not boost::iostreams, for example.
Rather than a custom std::ostream it might be easier -- and perhaps more flexible -- to implement a custom std::streambuf that can then be used with any std::ostream.
#include <streambuf>
template <class CharT, class Traits = std::char_traits<CharT>>
struct counting_streambuf: std::basic_streambuf<CharT, Traits> {
using base_t = std::basic_streambuf<CharT, Traits>;
using typename base_t::char_type;
using typename base_t::int_type;
std::streamsize count = 0;
std::streamsize xsputn(const char_type* /* unused */, std::streamsize n)
override
{
count += n;
return n;
}
int_type overflow(int_type ch)
override
{
++count;
return ch;
}
};
Then use as...
#include <iostream>
int
main (int argc, char **argv)
{
using char_type = decltype(std::cout)::char_type;
counting_streambuf<char_type> csb;
/*
* Associate the counting_streambuf with std::cout whilst
* retaining a pointer to the original std::streambuf.
*/
auto *oldbuf = std::cout.rdbuf(&csb);
std::cout << "Some text goes here...\n";
/*
* Restore the original std::streambuf.
*/
std::cout.rdbuf(oldbuf);
std::cout << "output length is " << csb.count << " characters\n";
}
Running the above results in...
output length is 23 characters
Edit: The original solution didn't overload overflow. This works on Linux but not on Windows. Thanks go to Peter Dimov from Boost, who found the solution.

C++ string formatting like Python "{}".format

I am looking for a quick and neat way to print in a nice table format with cells being aligned properly.
Is there a convenient way in c++ to create strings of substrings with certain length like python format
"{:10}".format("some_string")
In C++20 you'll be able to use std::format which brings Python-like formatting to C++:
auto s = std::format("{:10}", "some_string");
Until then you can use the open-source {fmt} formatting library, std::format is based on.
Disclaimer: I'm the author of {fmt} and C++20 std::format.
Try this https://github.com/fmtlib/fmt
fmt::printf("Hello, %s!", "world"); // uses printf format string syntax
std::string s = fmt::format("{0}{1}{0}", "abra", "cad");
You have many options here. For instance using streams.
source.cpp
std::ostringstream stream;
stream << "substring";
std::string new_string = stream.str();
#mattn was correct, the fmt library at https://github.com/fmtlib/fmt provides exactly this functionality.
The exciting news is this has been accepted into the C++20 standard.
You can use the fmt library knowing that it will be std::fmt in C++20
https://www.zverovich.net/2019/07/23/std-format-cpp20.html
https://en.cppreference.com/w/cpp/utility/format/format
you can quickly write a simple function to return a fixed length string.
We consider the str string is terminated by null, buf is already defined before calling the function.
void format_string(char * str, char * buf, int size)
{
for (int i=0; i<size; i++)
buf[i] = ' '; // initialize the string with spaces
int x = 0;
while (str[x])
{
if (x >= size) break;
buf[x] = str[x]; // fill up the string
}
buf[size-1] = 0; // termination char
}
Used as
char buf[100];
char str[] = "Hello";
format_string(str, buf, sizeof(buf));
printf(buf);
If you cannot use fmt as mentioned above the best way would be to use a wrapper class for formatting. Here is what I have done once:
#include <iomanip>
#include <iostream>
class format_guard {
std::ostream& _os;
std::ios::fmtflags _f;
public:
format_guard(std::ostream& os = std::cout) : _os(os), _f(os.flags()) {}
~format_guard() { _os.flags(_f); }
};
template <typename T>
struct table_entry {
const T& entry;
int width;
table_entry(const T& entry_, int width_)
: entry(entry_), width(static_cast<int>(width_)) {}
};
template <typename T>
std::ostream& operator<<(std::ostream& os, const table_entry<T>& e) {
format_guard fg(os);
return os << std::setw(e.width) << std::right << e.entry;
}
And then you would use it as std::cout << table_entry("some_string", 10). You can adapt table_entry to your needs. If you don't have class template argument deduction you could implement a make_table_entry function for template type deduction.
The format_guard is needed since some formatting options on std::ostream are sticky.

Generic API publishing techniques

I'm designing the next generation of a framework architecture for an internal project. Essentially there is a run time system that provides an API to applications which can be loaded/unloaded on the fly.
In the framework lives a library of custom "devices" The current interface to these devices is extremely generic; think posix load/unload/read/write/etc... One of the important principles of the framework is that the Apps need to know very little about device specifics.
Unfortunately, this interface has broken down to where the application developers end up rewriting common functions in the application itself.
I'm looking for suggestions or even a place to start reading about designing framework APIs like this. What is a good set of tools that a "device" author in the framework can use to publish an interface? What is the best way to publish an interface?
Ok - a proposal - may be vastly different from what you wanted, but feedback will help home in on something useful.
For synchronous "calls" you want your app module to send an indication of the driver function required and however many arguments, then retrieve some result. That can be achieved in a generic way by have a second, distinct read/write stream over which an encoding of the function and values is transmitted. So, say the driver API includes:
string get_stuff(string x, int y, double d[]);
This is NOT code - it's text that the framework/app can print/parse and potentially use to verify that data is sent and consumed correspondingly.
The app module then writes a "call" to the driver as a stream of function identifier and inputs, followed by a read of the result (assuming the app module has same-named variables holding the desired parameter values).
driver_api << "get_stuff " << escape(x) << ' ' << y << " [" << d.size() << "] ";
for (auto i = d.begin(); i != d.end(); ++i)
driver_api << ' ' << *i;
driver_api << '\n';
std::getline(driver_api, result);
It's a little more work (half an hour?) to create a custom stream wrapper that can wrap driver_api and insert the spaces or other separators/delimiters above, support streaming of containers, and/or send the data in a binary form, letting you write a cleaner and/or faster value-oriented version of the above, something like:
(driver_api << "get_stuff" << x << y << d) >> result;
You could also write normal C++ functions to wrap the above for the app module to call:
string get_stuff(const std::string& x, int y, const std::vector<double>& d)
{
string result;
(driver_api_ << "get_stuff" << x << y << d) >> result;
return result;
}
On the driver side, you'd write matching deserialisation routines to recover the app module specified values from the stream.
For specific architectures you may be able to get libraries to allow more convenient calls to functions, utilising debug information or ABI knowledge etc, whereas the above only needs Standard C++ and can be written to be portable (with a little care if doing binary serialisation of endian values).
EDIT - example of binary serialisation (just output for now / runs but output not carefully inspected for validity / most things fixed-width but strings are NUL terminated and containers prefixed by size / doesn't send following-field type information but very easy to create a version that does):
#include <iostream>
#include <vector>
#include <winsock2.h>
typedef signed char int8_t;
typedef signed short int16_t;
typedef signed int32_t;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned uint32_t;
class Binary_IOStream
{
public:
Binary_IOStream(std::istream& i, std::ostream& s) : i_(i), s_(s) { }
typedef Binary_IOStream This;
This& operator<<(int8_t x) { return write(x); }
This& operator<<(int16_t x) { return write(htons(x)); }
This& operator<<(int32_t x) { return write(htonl(x)); }
This& operator<<(uint8_t x) { return write(x); }
This& operator<<(uint16_t x) { return write(htons(x)); }
This& operator<<(uint32_t x) { return write(htonl(x)); }
This& operator<<(const std::string& s)
{ s_.write(s.c_str(), s.size() + 1); // include NUL, but could size-prefix
return *this; }
This& operator<<(double x) { return write(x); }
template <typename T>
This& operator<<(const std::vector<T>& v)
{ return write_range(v.begin(), v.end()); }
template <typename Iterator>
This& write_range(Iterator begin, Iterator end)
{
operator<<(std::distance(begin, end));
while (begin != end)
operator<<(*begin++);
return *this;
}
private:
template <typename T>
This& write(const T& t)
{ s_.write((const char*)&t, sizeof t); return *this; }
std::istream& i_;
std::ostream& s_;
};
int main()
{
Binary_IOStream bs(std::cin, std::cout);
bs << ('A' << 24) + ('b' << 16) + ('c' << 8) + 'D';
bs << "hello world!";
std::vector<double> v;
v.push_back(3.14);
v.push_back(2.72);
bs << v;
}

Problem using reinterpret_cast<> in c++

I am trying to cast a datastream into a struct since the datastream consists of fixed-width messages and each message has fulle defined fixed width fields as well. I was planning on creating a struct and then using reinterpret_cast to cast pointer to the datastream to the struct to get the fields. I made some test code and get weird results. Could any explain why I am getting these or how to correct the code. (the datastream will be binary and alpha numeric mixed but im just testing with strings)
#pragma pack(push,1)
struct Header
{
char msgType[1];
char filler[1];
char third[1];
char fourth[1];
};
#pragma pack(pop)
int main(void)
{
cout << sizeof(Header) << endl;
char* data = "four";
Header* header = reinterpret_cast<Header*>(data);
cout << header->msgType << endl;
cout << header ->filler << endl;
cout << header->third << endl;
cout << header->fourth << endl;
return 0;
}
The result that are coming up are
4
four
our
ur
r
I think the four, our and ur is printing since it cant find the null terminator. How do I get around the null terminator issue?
In order to be able to print an array of chars, and being able to distinguish it from a null-terminated string, you need other operator<< definitions:
template< size_t N >
std::ostream& operator<<( std::ostream& out, char (&array)[N] ) {
for( size_t i = 0; i != N; ++i ) out << array[i];
return out;
}
You're right about the lack of null terminator. The reason it's printing "ur" again is because you repeated the header->third instead of header->fourth. Instead of "char[1]", why not just declare those variables as "char"?
struct Header
{
char msgType;
char filler;
char third;
char fourth;
};
The issue is not reinterpret_cast (although using it is a very bad idea) but in the types of the things in the struct. They should be of type 'char', not of type 'char[1]'.
#pragma pack(push,1)
template<int N>
struct THeader
{
char msgType[1+N];
char filler[1+N];
char third[1+N];
char fourth[1+N];
};
typedef THeader<0> Header0;
typedef THeader<1> Header1;
Header1 Convert(const Header0 & h0) {
Header1 h1 = {0};
std::copy(h0.msgType, h0.msgType + sizeof(h0.msgType)/sizeof(h0.msgType[0]), h1.msgType);
std::copy(h0.filler, h0.filler+ sizeof(h0.filler)/sizeof(h0.filler[0]), h1.filler);
std::copy(h0.third , h0.third + sizeof(h0.third) /sizeof(h0.third [0]), h1.third);
std::copy(h0.fourth, h0.fourth+ sizeof(h0.fourth)/sizeof(h0.fourth[0]), h1.fourth);
return h1;
}
#pragma pack(pop)
int main(void)
{
cout << sizeof(Header) << endl;
char* data = "four";
Header0* header0 = reinterpret_cast<Header*>(data);
Header1 header = Convert(*header0);
cout << header.msgType << endl;
cout << header.filler << endl;
cout << header.third << endl;
cout << header.fourth << endl;
return 0;
}
In my experience, using #pragma pack has caused headaches -- partially due to a compiler that doesn't correctly pop, but also due to developers forgetting to pop in one header. One mistake like that and structs end up defined differently depending on which order headers get included in a compilation unit. It's a debugging nightmare.
I try not to do memory overlays for that reason -- you can't trust that your struct is properly aligned with the data you are expecting. Instead, I create structs (or classes) that contain the data from a message in a "native" C++ format. For example, you don't need a "filler" field defined if it's just there for alignment purposes. And perhaps it makes more sense for the type of a field to be int than for it to be char[4]. As soon as possible, translate the datastream into the "native" type.
Assuming you want to keep using an overlayable struct (which is sensible, since it avoids the copy in Alexey's code), you can replace your raw char arrays with a wrapper like the following:
template <int N> struct FixedStr {
char v[N];
};
template <int N>
std::ostream& operator<<( std::ostream& out, FixedStr const &str) {
char const *nul = (char const *)memchr(str.v, 0, N);
int n = (nul == NULL) ? N : nul-str.v;
out.write(str.v, n);
return out;
}
Then your generated structures will look like:
struct Header
{
FixedStr<1> msgType;
FixedStr<1> filler;
FixedStr<1> third;
FixedStr<40> forty;
};
and your existing code should work fine.
NB. you can add methods to FixedStr if you want (eg, std::string FixedStr::toString()) just don't add virtual methods or inheritance, and it will overlay fine.