decimal ascii value for unsigned char array - c++

How to convert char array to its equivalent ascii decimal array ? I tried in QT using QString and QbyteArray. But it is not working.
i/p: "1,9,10,2"
o/p: "4944574449484450" (1's ascii decimal value is 49,
, ascii decimal value is 44,
9's ascii decimal value is 57, and so on..).

How to convert char array to its equivalent ascii decimal array ?
You do not, it is already stored that way. If you want to print your array as decimal numbers for ASCII just output it accordingly (as integers):
char str[] = "1,9,10,2";
for( const char *s = str; *s; ++s ) std::cout << static_cast<int>( *s ) << ",";
// just output number instead of character
char in C++ is a numerical type similar to int, difference is std::ostream outputs char as a symbol and int and other integer types as integer.

You can easily do this way. It's C++ but it will work in C with proper includes and printf in place of std:cout.
int main() {
char input[] = "1,9,10,2";
char output[3*sizeof(input) + 1];
output[0] = '\0';
for (size_t i = 0; i < strlen(input); i++) {
sprintf(output, "%s%d", output, input[i]);
}
std::cout << input << std::endl;
std::cout << output << std::endl;
return 0;
}
Followed some hint from #Nathan, it should be better now...

This should work
char arr[] = {'1','9','2'};
std::vector<int> vec(size); //size of the char array - in this case 3
for(int i = 0; i < size; i++)
{
vec[i] = arr[i];
}

Related

Convert string to bytes in c++

I am new to c++ and still trying to feel my way in. I have attempted to adapt a function I have found on SO to convert my string into bytes as I need:
void hexconvert(const char *text, unsigned char bytes[])
{
int i;
int temp;
for (i = 0; i < 4; ++i) {
sscanf(text + 2 * i, "%2x", &temp);
bytes[i] = temp;
}
cout << bytes;
}
hexconvert("SKY 000.001\n", );
Issues I have are:
1) I am not sure how to amend the for loop to handle my string.
2) I am not sure what I should use as the input for the second parameter in the function.
Can anyone assist?
Thanks
This is my suggested solution. I used it to encode a GUID as a byte array. It should achieve higher performance than having to do printf on all the characters.
typedef unsigned char byte;
std::map<char, byte> char2hex =
{
{'0', 0x0},
{'1', 0x1},
{'2', 0x2},
{'3', 0x3},
{'4', 0x4},
{'5', 0x5},
{'6', 0x6},
{'7', 0x7},
{'8', 0x8},
{'9', 0x9},
{'a', 0xa},
{'b', 0xb},
{'c', 0xc},
{'d', 0xd},
{'e', 0xe},
{'f', 0xf}
};
void convertToBytes(const string &chars, byte bytes[])
{
for (size_t i = 0; i < chars.length() / 2; i++) {
byte b1 = (byte)(char2hex[chars[2*i]] << 4);
byte b2 = char2hex[chars[2*i+1]];
byte f = b1 | b2;
*(bytes + i) = f;
}
}
Remember that two ascii characters make up one byte, so for every pair of characters, I have to convert the first character to byte, then shift it up by 4 bits, then or it with the next character to get one byte.
To print a string as bytes:
const size_t length = data.length();
for (size_t i = 0; i < length; ++i)
{
unsigned int value = data[i];
std::cout << std::dec << std::fill(' ') << value
<< " (0x" << std::setw(2) << std::setfill('0') << std::hex << value << ')'
<< "\n";
}
Some important rules to remember:
1. Copy the character into an integer type variable, so that cout doesn't print as character.
2. Bytes are unsigned.
3. When filling the width with 0 for hex, remember to reset it to space before printing decimal.
4. Use std::hex for printing in hexadecimal, and remember to reset it with std::dec afterwards (if you are printing in decimal afterwards).
See <iomanip>.
Edit 1: C-Style
To use the C language style:
static const char data[] = "Hello World!";
const size_t length = strlen(data);
for (size_t i = 0; i < length; ++i)
{
printf("%3d (0x%02X)\n", data[i], data[i]);
}
The above assumes that data is a character array, nul terminated.

How to convert a hexadecimal value contained in a char (byte) to an integer?

I just want to know how to convert an hexadecimal value contained in a char (byte) into an integer. I want to convert the color buffer from a .bmp file which is of course in hexadecimal and convert it in integers.
For example :
char rgb_hexa[3] = {0xA8, 0xF4, 0xD3};
After conversion :
int rgb_int[3] = {168, 244, 211};
I always tried to use strtol but it seems to only works with char *. I tried to do the following test but it does not work :
char src_hexa_red = 0xA8;
char src_hexa_green = 0xF4;
char src_hexa_blue = 0xD3;
std::cout << "R=" << strtol(&src_hexa_red, (char**)NULL, 16) << ", G="
<< strtol(&src_hexa_green, (char**)NULL, 16) << ", B="
<< strtol(&src_hexa_blue, (char**)NULL, 16) << std::endl;
Does anyone can help me please ?
Thanks in advance for your help.
A single char never contains hexadecimal. Nor decimal, for
that matter. Strictly speaking, a char contains an integral
value; the C++ standard requires it to use a binary
representation for the value. The value can be interpreted as
a character, but this is not always the case; there are contexts
where the integral value is used directly.
Hexadecimal and decimal are just ways of representing the value
in text format. They only have meaning when dealing with text.
for(int i = 0; i < 3; ++i)
rgb_int[i] = (unsigned char)rgb_hexa[i];
char is an integer type in C & C++ just like short, int and long. It's just the smallest integer type. Mostly, char is signed & the maximum which can fit is 127. So if the hex value was below or equal to 127, you wouldn't have to do anything. However, in this case the hex values you have are > 127 - hence you would have to cast them to unsigned to get the value you want.
Note that both the statements are identical to the compiler.
char rgb_hexa[3] = {0xA8, 0xF4, 0xD3};
char rgb_hexa[3] = {168, 244, 211};
You could have even used octal if you wanted
char rgb_hexa[3] = {0250, 0364, 0323};
It's all the same.
The values in the char array are already in a binary form, so you can cast them to an int, if you need them as such.
int v = (int)rgb_hexa[0];
You should be aware though that using signed char they will be sign extendend.
So 0xFA becomes 0xFFFFFFFA when converted to an int.
If you want to keep the values then you should use unsigned char and unsigned int which makes it 0x000000FA depending on how you want to use the values.
int v0 = (int)a[1]; <-- sign extended
unsigned int v1 = (unsigned int)a[1]; <-- sign extended
unsigned int v1 = (unsigned int)((unsigned char *)a)[1]; <-- not sign extended
You don't need to do any conversion because hexa/decimal are just ways to represent values.
For example 0xA8 in hexadecimal is the same value as 180 in decimal and 250 in octal. As in languages for example, "two", "deux" and "dois" represent all the same number (2).
In your case if you want to print the values do the following:
short y = (short) x & 0x00FF; // x is the char you want to print
cout << "Value (decimal): " << y;
cout << "Value (hexa): " << hex << y;
cout << "Value (oct): " << oct << y;
Why can't you do this
int main(int argc, char *argv[])
{
char rgb_hexa[3] = {0xA8, 0xF4, 0xD3};
int rgb_int[3] = {0,};
int i = 0;
for( i = 0 ; i < 3 ;i++)
rgb_int[i] = (unsigned char)rgb_hexa[i];
for( i = 0 ; i < 3 ;i++)
printf("%d ",rgb_int[i]);
return 0;
}
pretty straight forward ..
For type conversion, there is static_cast:
unsigned char source = 168; // note that this has for compiler same meaning as:
// unsigned char source = 0xA8; // because data is stored in binary anyway
unsigned int dest = static_cast<int>(source); // the conversion
std::cout << source << std::endl;
dest and source have same binary meaning, but they are of a different type.
I've used unsigned types, because signed char stores usually values from -127 to 127, see limits.

Byte Array to Hex Digits (0 to 9 and A to F only)

I am trying to convert a "double" value (say 1.12345) to 8 byte hex string. I am using the following function to convert double value to hex string.
std::string double_to_hex_string(double d)
{
unsigned char *buffer = (unsigned char*)&d;
const int bufferSize = sizeof(double);
char converted[bufferSize * 2 + 1];
//char converted[bufferSize];
int j = 0;
for(int i = 0 ; i < bufferSize ; ++i)
{
sprintf(&converted[j*2], "%02X", buffer[i]);
++j;
}
string hex_string(converted);
return hex_string;
}
This function returns the 16 byte hex string. I then compress this string to fit into 8 bytes through this code
string hexStr = double_to_hex_string(TempD);
unsigned char sample[8];
for ( int i = 0; i < hexStr.length() / 2 ; i++)
{
sscanf( (hexStr.substr(i*2,2)).c_str(), "%02X", &sample[i]);
}
Now, how can I get the hex digits representing these 8 bytes in "sample" array. There should be only one hex digit per byte. I need to append this 8 byte hex string to a global string.
If there is any other solution which can convert a double value to 8 hex digits and vice versa, that would be highly appreciated.
Regards.
A hexidecimal digit represents half a byte, so if you are limited to 8 hex digits you are also limited to storing 4 bytes.
This solution will encode the number from a float, which is commonly 4 bytes.
std::string double_to_hex_string(double d)
{
// Create a stream that writes 2 digit hex values
std::stringstream stream;
stream << std::hex << std::setfill('0');
float f = d;
const unsigned char *buffer = reinterpret_cast<unsigned char*>( &f );
const unsigned char *buffer_end = buffer + sizeof(f);
// Write each byte as 2 character hex.
while ( buffer != buffer_end )
{
stream << std::setw(2) << static_cast<int>( *buffer );
++buffer;
}
return stream.str();
}

Conversion from Integer to BCD

I want to convert the integer (whose maximum value can reach to 99999999) in to BCD and store in to array of 4 characters.
Like for example:
Input is : 12345 (Integer)
Output should be = "00012345" in BCD which is stored in to array of 4 characters.
Here 0x00 0x01 0x23 0x45 stored in BCD format.
I tried in the below manner but didnt work
int decNum = 12345;
long aux;
aux = (long)decNum;
cout<<" aux = "<<aux<<endl;
char* str = (char*)& aux;
char output[4];
int len = 0;
int i = 3;
while (len < 8)
{
cout <<"str: " << len << " " << (int)str[len] << endl;
unsigned char temp = str[len]%10;
len++;
cout <<"str: " << len << " " << (int)str[len] << endl;
output[i] = ((str[len]) << 4) | temp;
i--;
len++;
}
Any help will be appreciated
str points actually to a long (probably 4 bytes), but the iteration accesses 8 bytes.
The operation str[len]%10 looks as if you are expecting digits, but there is only binary data. In addition I suspect that i gets negative.
First, don't use C-style casts (like (long)a or (char*)). They are a bad smell. Instead, learn and use C++ style casts (like static_cast<long>(a)), because they point out where you are doing things that are dangeruos, instead of just silently working and causing undefined behavior.
char* str = (char*)& aux; gives you a pointer to the bytes of aux -- it is actually char* str = reinterpret_cast<char*>(&aux);. It does not give you a traditional string with digits in it. sizeof(char) is 1, sizeof(long) is almost certainly 4, so there are only 4 valid bytes in your aux variable. You proceed to try to read 8 of them.
I doubt this is doing what you want it to do. If you want to print out a number into a string, you will have to run actual code, not just reinterpret bits in memory.
std::string s; std::stringstream ss; ss << aux; ss >> s; will create a std::string with the base-10 digits of aux in it.
Then you can look at the characters in s to build your BCD.
This is far from the fastest method, but it at least is close to your original approach.
First of all sorry about the C code, I was deceived since this started as a C questions, porting to C++ should not really be such a big deal.
If you really want it to be in a char array I'll do something like following code, I find useful to still leave the result in a little endian format so I can just cast it to an int for printing out, however that is not strictly necessary:
#include <stdio.h>
typedef struct
{
char value[4];
} BCD_Number;
BCD_Number bin2bcd(int bin_number);
int main(int args, char **argv)
{
BCD_Number bcd_result;
bcd_result = bin2bcd(12345678);
/* Assuming an int is 4 bytes */
printf("result=0x%08x\n", *((int *)bcd_result.value));
}
BCD_Number bin2bcd(int bin_number)
{
BCD_Number bcd_number;
for(int i = 0; i < sizeof(bcd_number.value); i++)
{
bcd_number.value[i] = bin_number % 10;
bin_number /= 10;
bcd_number.value[i] |= bin_number % 10 << 4;
bin_number /= 10;
}
return bcd_number;
}

how do I convert an integer which is defined in an int array to hex?

I have an int array that represents a very large number such as:
// ...
unsigned int n1[200];
// ...
n1 = {1,3,4,6,1,...} ==> means my number is 13461...
How can I convert that large number to its hex value?
So here is my take on the problem:
You have an array of digits.
You want to build an unsigned int from this array of digits.
The array of digits could be either HEX digits, or DECIMAL digits.
To build this unsigned long long, assuming an array of DECIMAL digits:
unsigned long long myNum = 0;
unsigned int n1[200];
for (int i=0; i < n1.length ; i++ ){
myNum += pow(10,i) * n1[n1.length - i];
}
To build this unsigned long long, assuming an array of HEX digits:
for (int i=0; i < n1.length ; i++ ){
myNum += pow(16,i)* n1[n1.length - i];
}
(Notice the base 16)
Disclaimer: limited to exactly 16 digits MAX stored in your array. After that you will overrun the buffer
If it is just a matter of DISLAYING the number in the correct format...
Well, an int is an int is an int... (in memory).
There are 10 fingers on my hands whether or not I call that number 10, or A.
If you want to format the number for DISPLAY in hex, then try something like:
unsigned int i = 10;
//OR
unsigned int i = 0xA;
printf("My number in hex: %x", i);
printf("My number in decimal: %d", i);
I'm unsure if you want the hexadecimal represented as a string. If that's
the case, here's some code:
#include <iostream>
#include <stack>
using namespace std;
string toHexa(int num){
string digit = "0123456789ABCDEF", numStr = "";
stack<char> s;
do {
s.push(digit[num%16]);
num /= 16;
} while (num != 0);
while (!s.empty()){
numStr += s.top();
s.pop();
}
return numStr;
}
int main(){
int num = 235; // EB in hexa
cout << num << " to hexadecimal: " << toHexa(num) << endl;
return 0;
}
You could use the GMP library to make this relatively straightforward.
Use basic_stringstream<unsigned int> to wrap your array.
Use operator << to read it into a mpz_t variable.
Create another basic_stringstream<unsigned int> for your result.
Use std::hex and operator >> to write the variable back out in hexadecimal.
That would work on ASCII digits, but yours aren't. You can still use GMP, but you'll want to use the mpn_get_str and mpn_set_str functions instead. You'll need to copy your digits into an unsigned char[] and then you can specify the base for conversion to mp_limb_t and back to a string of digits.