2

I have a simple program converting dynamic char array to hex string representation.

#include <iostream>
#include <sstream>
#include <iomanip>
#include <string>
using namespace std;


int main(int argc, char const* argv[]) {
    int length = 2;
    char *buf = new char[length];
    buf[0] = 0xFC;
    buf[1] = 0x01;

    stringstream ss;
    ss << hex << setfill('0');
    for(int i = 0; i < length; ++i) {
        ss << std::hex << std::setfill('0') << std::setw(2) << (int) buf[i] << " ";
    }
    string mystr = ss.str();
    cout << mystr << endl;
}

Output:

fffffffc 01

Expected output:

fc 01

Why is this happening? What are those ffffff before fc? This happens only on certain bytes, as you can see the 0x01 is formatted correctly.

2
  • Removing the hex, fill, and width modifiers, and just sending (int)buf[i] to stdout will provide a pretty significant hint as to what is happening. Commented Dec 7, 2019 at 11:53
  • That is correct, thank you! Commented Dec 7, 2019 at 11:54

2 Answers 2

5

Three things you need to know to understand what's happening:

  1. The first thing is that char can be either signed or unsigned, it's implementation (compiler) specific

  2. When converting a small signed type to a large signed type (like e.g. a signed char to an int), they will be sign extended

  3. How negative values are stored using the most common two's complement system, where the highest bit in a value defines if a value is negative (bit is set) or not (bit is clear)

What happens here is that char seems to be signed, and 0xfc is considered a negative value, and when you convert 0xfc to an int it will be sign-extended to 0xfffffffc.

To solve it use explicitly unsigned char and convert to unsigned int.

Sign up to request clarification or add additional context in comments.

Comments

3

This is called "sign extension".

char is a signed type, so 0xfc will become negative value if you force it in to a char. Its decimal value is -4

When you cast it to int, it extends the sign bit to give you the same value. (It happens here (int) buf[i])

On your system, int is 4 bytes, so you get the extra bytes filled with ff.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.