Initializing an unsigned char array with hex values in C++

28,639

Solution 1

A char is an 8-bit value capable of storing -128 <= n <= +127, frequently used to store character representations in different encodings and commonly - in Western, Roman-alphabet installations - char is used to indicate representation of ASCII or utf encoded values. 'Encoded' means the symbols/letter in the character set have been assigned numeric values. Think of the periodic table as an encoding of elements, so that 'H' (Hydrogen) is encoded as 1, Germanium as 32. In the ASCII (and UTF-8) tables, position 32 represents the character we call "space".

When you use operator << on a char value, the default behavior is to assume you are passing it a character encoding, e.g. an ASCII character code. If you do

char c = 'z';
char d = 122;
char e = 0x7A;
char f = '\x7a';
std::cout << c << d << e << f << "\n";

All four assignments are equivalent. 'z' is a shortcut/syntactic-sugar for char(122), 0x7A is hex for 122, and '\x7a' is an escape that forms the ascii character with a value of 0x7a or 122 - i.e. z.

Where many new programmers go wrong is that they do this:

char n = 8;
std::cout << n << endl;

this does not print "8", it prints ASCII character at position 8 in the ASCII table.

Think for a moment:

char n = 8;  // stores the value 8
char n = a;  // what does this store?
char n = '8'; // why is this different than the first line?

Lets rewind a moment: when you store 120 in a variable, it can represent the ASCII character 'x', but ultimately what is being stored is just the numeric value 120, plain and simple.

Specifically: When you pass 122 to a function that will ultimately use it to look up a font entry from a character set using the Latin1, ISO-8859-1, UTF-8 or similar encodings, then 120 means 'z'.

At the end of the day, char is just one of the standard integer value types, it can store values -128 <= n <= +127, it can trivially be promoted to a short, int, long or long long, etc, etc.

While it is generally used to denote characters, it also frequently gets used as a way of saying "I'm only storing very small values" (such as integer percentages).

int incoming = 5000;
int outgoing = 4000;
char percent = char(outgoing * 100 / incoming);

If you want to print the numeric value, you simply need to promote it to a different value type:

std::cout << (unsigned int)test << "\n";
std::cout << unsigned int(test) << "\n";

or the preferred C++ way

std::cout << static_cast<unsigned int>(test) << "\n";

Solution 2

I think (it's not completely clear what you are asking) that the answer is as simple as this

std::cout << "Please be a value! -----> " << static_cast<unsigned>(test) << std::endl;

If you want to output the numeric value of a char or unsigned char, you have to cast it to an int or unsigned first.

Not surprisingly, by default, chars are output as characters not integers.

BTW this funky code

char buff[100];
sprintf(buff,"The program was run with the following command: %d",n);
std::cout << buff << std::endl;

is more simply written as

std::cout << "The program was run with the following command: " << n << std::endl;
Share:
28,639
hatgirl
Author by

hatgirl

Updated on November 03, 2020

Comments

  • hatgirl
    hatgirl over 3 years

    I would like to initialize an unsigned char array with 16 hex values. However, I don't seem to know how to properly initialize/access those values. When I try to access them as I might want to intuitively, I'm getting no value at all.

    This is my output

    The program was run with the following command: 4
    Please be a value! -----> p
    Here's some plaintext 
    

    when run with the code below -

    int main(int argc, char** argv)
    {
      int n;
      if (argc > 1) {
        n = std::stof(argv[1]);
      } else {
        std::cerr << "Not enough arguments\n";
        return 1;
      }
    
      char buff[100];
      sprintf(buff,"The program was run with the following command: %d",n);
      std::cout << buff << std::endl;
    
    unsigned char plaintext[16] = 
       {0x0f, 0xb0, 0xc0, 0x0f,
        0xa0, 0xa0, 0xa0, 0xa0,
        0x00, 0x00, 0xa0, 0xa0,
        0x00, 0x00, 0x00, 0x00};
    
    unsigned char test = plaintext[1]^plaintext[2];
    
    std::cout << "Please be a value! -----> " << test << std::endl;
    
    std::cout << "Here's some plaintext " << plaintext[3] << std::endl;
    
      return 0;
    }
    

    By way of context, this is part of a group project for school. We are ultimately trying to implement the Serpent cipher, but keep on getting tripped up by unsigned char arrays. Our project specification says that we must have two functions that take what would be Byte arrays in Java. I assume the closest relative in C++ is an unsigned char[]. Otherwise I would use vector. Elsewhere in the code I've implemented a setKey function which takes an unsigned char array, packs its values into 4 long long ints (the key needs to be 256 bits) and performs various bit-shifting and xor operations on those ints to generate the keys necessary for the cryptographic algorithm. Hope that's enough background on what I'm looking to do. I'm guessing I'm just overlooking some basic C++ functionality here. Thanks for any and all help!

  • Ben Voigt
    Ben Voigt over 9 years
    A char can certainly store values from 0 to 127. Anything else is implementation-defined.