views:

122

answers:

4

I don't see this an option in things like sprintf().

How would I convert the letter F to 255? Basically the reverse operation of conversion using the %x format in sprintf?

I am assuming this is something simple I'm missing.

+3  A: 
char const* data = "F";
int num = int(strtol(data, 0, 16));

Look up strtol and boost::lexical_cast for more details and options.

Roger Pate
+3  A: 

Use the %x format in sscanf!

Alex Martelli
A: 

You can't get (s)printf to convert 'F' to 255 without some black magic. Printf will convert a character to other representations, but won't change its value. This might show how character conversion works:

printf("Char %c is decimal %i (0x%X)\n", 'F', 'F', 'F');  
printf("The high order bits are ignored: %d: %X -> %hhX -> %c\n",  
                   0xFFFFFF46,  0xFFFFFF46, 0xFFFFFF46, 0xFFFFFF46);

produces

Char F is decimal 70 (0x46)  
The high order bits are ignored: -186: FFFFFF46 -> 46 -> F

Yeah, I know you asked about sprintf, but that won't show you anything until you do another print.

The idea is that each generic integer parameter to a printf is put on the stack (or in a register) by promotion. That means it is expanded to it's largest generic size: bytes, characters, and shorts are converted to int by sign-extending or zero padding. This keeps the parameter list on the stack in sensible state. It's a nice convention, but it probably had it's origin in the 16-bit word orientation of the stack on the PDP-11 (where it all started).

In the printf library (on the receiving end of the call), the code uses the format specifier to determine what part of the parameter (or all of it) are processed. So if the format is '%c', only 8 bits are used. Note that there may be some variation between systems on how the hex constants are 'promoted'. But if a value greater thann 255 is passed to a character conversion, the high order bits are ignored.

gary
+1  A: 

The C++ way of doing it, with streams:

#include <iomanip>
#include <iostream>
#include <sstream>

int main() {
    std::string hexvalue = "FF";
    int value;
    // Construct an input stringstream, initialized with hexvalue
    std::istringstream iss(hexvalue);
    // Set the stream in hex mode, then read the value, with error handling
    if (iss >> std::hex >> value) std::cout << value << std::endl;
    else std::cout << "Conversion failed" << std::endl;
}

The program prints 255.

Tronic
A pedantic solution would not only check whether the conversion succeeded but also that iss has eof flag set (no data was left unread). I have left that out as even the very basic error handling must be confusing enough.
Tronic