I have a char '╞' with ASCII value (198). How I can manipulate this char such that the resulting char will be one of the following?
0 to 9 and A to F
Later on, I want to convert the resulting char back into the original char i.e. '╞'
I guess this is a question about decimal to hex conversion. I would do it like this
char dec = 198;
char hex[3];
sprintf(hex, "%02X", (unsigned char)dec);
To convert back it would be
int tmp;
sscanf(hex, "%X", &tmp);
dec = tmp;
There's other ways, using std::stringstream for instance, but the above is fine by me.
Related
Assume I have a string s that represents a hex value:
string s="0x80";
I want to assign the value of s to v, where v is defined as:
unsigned char v;
What is the simplest way of doing it?
Why do I need it? Because in here, a bloom filter is represented as a vector of unsigned char where each char represents 8 bits. I want to access each char, perform some computation on it, and then store it back in a compatible form. Also, when I print each element of the vector (which is of type unsigned char) it appears in a hex form, e.g. 3a, 98, etc.
Construct a std::istringstream from the string.
Extract the number from the istringstream by indicating that the stream contains data in hex format.
Assign the number to a char.
std::string s="0x80";
std::istringstream str(s);
int num;
str >> std::hex >> num;
unsigned char v = num;
Convert string to integer:
unsigned char num = std::stoi(s, nullptr, 0);
How to convert variable unsigned char with HEX value to variable int with DEC value. I have got:
unsigned char length_hex = 0x30; // HEX
How to convert to int DEC?
int length_dec = length_hex; // With result length_dec = 48
As some people have commented the conversion is automatic. Try:
int main (void)
{
unsigned char length_hex = 0x30;
printf("0x30 is char:%c and int:%d.",length_hex,length_hex);
return 0;
}
and see what you get - when you convert it to a char it's '0' (the character 0) and as an int it's 48. Also, it doesn't really matter if I save the constant 0x30 as an int or char. Just look at:
printf("0x30 is char:%c and int:%d.",0x30,0x30);
When I use the char datatype to add two numbers, I get the sum of the ASCII code of the characters and not the numbers itself. When I researched on the internet, various sites say that the char type can indeed be used to handle one byte numbers. But in reality, I get the sum of ASCII values. Why is this happening? Below is just a sample code which illustrates the problem:
uint8_t rows,cols; //uint8_t is just a typedef for char
cin >> rows;
cout << rows + 1 << endl;
When people talk about "one-byte numbers", they're talking about 8-bit values, ranging from -128 to 127 for a char, or 0 to 255 for an unsigned char, also known as octets. These can be converted directly to larger integer types and to floats:
char eight_bit = 122;
float floating_point = eight_bit; // = 122.0
If you're trying to convert a digit value such as '1' into the numeric value it represents, there's stoi:
#include <string>
int ctoi(char c) {
std::string temp;
temp.push_back(c);
return std::stoi(temp);
}
Chars store the ASCII equivalent of a character as an integer.
For example
char value = 'A' // == int 65
It's best you use a short integer to store numbers, but if you really want to, you can do something like this;
char value1 = '2';
char value2 = '5';
char sum = (value1 + value2) - '0'; // int value of sum would be 7
When you use char, you use signed 8 bit data type (mostly).
And you get "sum of ASCII" only because std::cout is programmed to display char as ASCII character.
Try
cout << stratic_cast<int16_t>(rows) + 1 << endl;
And you will see that you get the 'number' rather than an 'ASCII character'.
NOTE
uint8_t is not (or probably should not be) char since char is defined as signed data type while uint* stands for unsigned.
I have the following simple program that uses a union to convert between a 64 bit integer and its corresponding byte array:
union u
{
uint64_t ui;
char c[sizeof(uint64_t)];
};
int main(int argc, char *argv[])
{
u test;
test.ui = 0x0123456789abcdefLL;
for(unsigned int idx = 0; idx < sizeof(uint64_t); idx++)
{
cout << "test.c[" << idx << "] = 0x" << hex << +test.c[idx] << endl;
}
return 0;
}
What I would expect as output is:
test.c[0] = 0xef
test.c[1] = 0xcd
test.c[2] = 0xab
test.c[3] = 0x89
test.c[4] = 0x67
test.c[5] = 0x45
test.c[6] = 0x23
test.c[7] = 0x1
But what I actually get is:
test.c[0] = 0xffffffef
test.c[1] = 0xffffffcd
test.c[2] = 0xffffffab
test.c[3] = 0xffffff89
test.c[4] = 0x67
test.c[5] = 0x45
test.c[6] = 0x23
test.c[7] = 0x1
I'm seeing this on Ubuntu LTS 14.04 with GCC.
I've been trying to get my head around this for some time now. Why are the first 4 elements of the char array displayed as 32 bit integers, with 0xffffff prepended to them? And why only the first 4, why not all of them?
Interestingly enough, when I use the array to write to a stream (which was the original purpose of the whole thing), the correct values are written. But comparing the array char by char obviously leads to problems, since the first 4 chars are not equal 0xef, 0xcd, and so on.
Using char is not the right thing to do since it could be signed or unsigned. Use unsigned char.
union u
{
uint64_t ui;
unsigned char c[sizeof(uint64_t)];
};
char gets promoted to an int because of the prepended unary + operator. . Since your chars are signed, any element with the highest by set to 1 is interpreted as a negative number and promoted to an integer with the same negative value. There are a few different ways to solve this:
Drop the +: ... << test.c[idx] << .... This may print the char as a character rather than a number, so is probably not a good solution.
Declare c as unsigned char. This will promote it to an unsigned int.
Explicitly cast +test.c[idx] before it is passed: ... << (unsigned char)(+test.c[idx]) << ...
Set the upper bytes of the integer to zero using binary &: ... << +test.c[idx] & 0xFF << .... This will only display the lowest-order byte no matter how the char is promoted.
Use either unsigned char or use test.c[idx] & 0xff to avoid sign extension when a char value > 0x7f is converted to int.
It is unsigned char vs signed char and its casting to integer
The unary plus causes the char to be promoted to a int (integral promotion). Because you have signed chars the value will be used as such and the other bytes will reflect that.
It is not true that only the four are ints, they all are. You just don't see it from the representtion since the leading zeroes are not shown.
Either use unsigned chars or & 0xff for promotion to get the desired result.
I am having trouble with unsigned char *. Here is my code:
unsigned char *str=NULL;
str= (unsigned char*) realloc(str, 10*sizeof(unsigned char));
int number=10;
str[0]=(unsigned char) number;
Whenever I try to see str[0] with cout, it shows something else other than 10. I also have trouble when putting other variable into str:
unsigned char c='c';
str[0]=c;
cout<<str[0];
str[0] would output a. What am I missing?
s[0] = 10; means put character code 10 into the first location of array s. Try:
s[0] = '1'; s[1] = '0'; s[2] = '\0';
Probably you would like instead to use the function itoa(10, s, 10);
See itoa manual, the function itoa is declared as...
char* itoa(int valueToConvert, char* outputBuffer, int base);
If you try to do cout << character; it will print the character, not the character code. To print the character code you should do cout << (int)character;. Don't use unsigned char for characters, characters are, well, signed chars, simply chars, for friends.