How to tell printf() to get the value from the untyped (or byte-sequence) buffer
I have a buffer of raw values, say, void* buffer
or better, char* buffer
- a raw byte stream, for example, read from a file. I'd like the bytes in the buffer to be represented and displayed in several ways, for example, as a float
, or as a long long
in runtime. I'd ask a user for des开发者_运维技巧ired format string, for example, %10d
, and pass the format string to printf()
. However, there are no format specifiers in printf()
so it would expect an untyped (or byte-stream) buffer as a second argument?
How can I tell printf()
to get the expected data from the buffer and display it according to the given format string? I won't like to use switch-case
or if-then
trees.
You need to deserialize the bytestream into values. Both bytes and float
s are non-text binary, but the translation between them still depends on endianness and, to be pedantic, whether the machine has IEEE FP math.
Once you've correctly read the bytes into native values, just use the regular format specifiers.
If you're sure that no byte translation is necessary, just cast void*
to the desired float*
or whatever, dereference the pointer, and print it as usual. But, that's very unportable and can crash on the wrong machine.
void printUINT(const unsigned char *b,size_t bsize)
{
size_t len=0;
bsize-=sizeof(int);
for(; len<=bsize; len+=sizeof(int));
printf("%u\n",*(unsigned*)&b[len]);
}
void printULONG(const unsigned char *b,size_t bsize)
{
size_t len=0;
bsize-=sizeof(long);
for(; len<=bsize; len+=sizeof(long));
printf("%lu\n",*(unsigned long*)&b[len]);
}
void printDOUBLE(const unsigned char *b,size_t bsize)
{
size_t len=0;
bsize-=sizeof(double);
for(; len<=bsize; len+=sizeof(double));
printf("%f\n",*(double*)&b[len]);
}
It can't be done without a switch()
-type construction. If printf()
had such functionality, it would be implemented within the notional switch() { }
block that handles the format specifiers, anyway.
精彩评论