Hexadecimal in String to Hexadecimal in Integer - c++

I want to know how to convert something like string x = "1f" to int y = 0x1f, every topic I found was solved by turning it to simply the integer value of it (31) or turning the string to a hexadecimal equivalent "Hello" > 48656C6C6F
std::stringstream Strm;
std::string Stng = "1f";
Strm << Stng;
int Hexa;
Strm >> std::hex >> Hexa;
cout << Hexa;
This closest I could get to it (but turned out it just converts it to integer)
EDIT: I guess my problem was I didn't know it must be stored as an integer and can be only shown as hexadecimal if i add std::hex after cout, that was stupid sorry

Integers don't carry labels saying 'I'm a decimal integer' or 'I'm a hexadecimal integer'. All integers are the same. So if you have found some code that converts a hexadecimal string to an integer then that is the code you should use.
Once you have your integer you can then choose to print it out in hexadecimal if you want. You do that with hex
int hexa = ...;
cout << hex << hexa; // prints an int in hexadecimal form

One quite fast solutions is using boost::lexical cast. You can find everything here http://www.boost.org/doc/libs/1_53_0/doc/html/boost_lexical_cast.html

You have two choices:
std::strtol
std::stoi
The last will throw an exception if the input string is not a proper hexadecimal number.
And remember, in the computer all integers are stored in binary, hexadecimal is just a presentation. For example, the ASCII character 'a' is the same as decimal number 97 and the same as octal number 141 and the same as hexadecimal number 61 and the same as binary number (which it is ultimately is stored as in memory) 01100001.

Related

Converting a hexadecimal number represented in ASCII characters to a decimal integer in C/C++

my problem is as follows.
I'm reading a piece of ascii data from a sensor, let's say it's "400". It's stored in an array of characters. In hex (ascii) that would be { 0x34, 0x30, 0x30 }.
What I'm trying to get from that set of characters is an integer in decimal representative of hex 0x400, which would be 1024. All the other numeric values in this array of ascii characters are represented in decimal, so I've been using this:
int num_from_ascii(char reading[], int start, int length){
printf("++++++++num_from_ascii+++++++++\n");
char radar_block[length];
for(int i = 0; i < length; i++){
radar_block[i] = reading[start + i];
printf("%02x ", reading[start + i]);
}
printf("\n");
return atoi(radar_block);
}
This obviously just gives me back 400, but I need a decimal integer from a hex value. Any advice?
As Eugene has suggested, all you need to do is replace atoi(radar_block) by strtol(radar_block, NULL, 16). That takes a "base" argument, which can be 10 for decimal, 16 for hex (which is what you want), etc or 0 to auto-detect using the C++ rules (leading "0x" for hex, leading "0" for octal).
You should never use atoi anyway because it does not handle invalid inputs safely. strtol does everything that atoi does, has well defined errno for all edge cases, and also allows you to distinguish "0" from non-numeric input.
As user3121023 mentioned, don't forget to NUL-terminate the string you pass to strtol (this is a serious bug in your code calling atoi as well).

Formatting output of a signed hex digits

I have been using stringstream to convert my data and it has been working great except for one case.
I am subtracting two integer values that can end up being negative or positive. I take that value and send it to my stringstream object using std::hex as well as it gets dumped to std::cout.
My problem is my field for this value can only be 3 digits long and when I get a negative value it pads it with too many leading F's. I can't seem to get any std functions to help (setw, setfill, ...).
Can anyone point me in the right direction?
Example:
Value - Value = -9, So what I want is FF9 but what I get is FFFFFFF9.
My code to send the value to my stringstream object ss
ss << hex << value - LocationCounter;
You are trying to output a value that is 12 bits max in size. There is no 12-bit data type, so the closest you can get is to use a 16-bit signed type with its high 4 bits set to 0. For instance, calculate your desired value into an 8-bit signed type first (which will reduce its effective range to -128 .. 127), then sign-extend it to a 16-bit signed type, zero the high 4 bits, and finally output the result as hex:
signed char diff = (signed char)(value - LocationCounter);
// the setw() and setfill() are used to pad
// values that are 8 bits or fewer in size...
ss << hex << setw(3) << setfill('0') << (((signed short)diff) & 0x0fff);
To read the value back, read the 12-bit hex into a signed short and then truncate its value to a signed char:
signed short tmp;
ss >> hex >> tmp;
signed char diff = (signed char)tmp;

Addition of an integer with an hex string

What should I do to add an integer to an hex string.
Say my hex string is:
11'h000
And I want to add integer 7 to it. Output it should give should be
11'h007
If given 11'h00e, Adding integer 1 to it should give me 11'h00f.
Are there any predefined functions in c++? I could have write my switch-case statements to get it but looking for a compact way.
The best way? Don't confuse formatting of a number with a number.
Use
int x = std::stoi(s/*a hexadecimal string*/, nullptr, 16 /*hexadecimal*/);
x++; /*all your arithmetic operations here*/
std::cout/*or a suitable stream*/ << std::hex << x;

c++ convert integer to 8 char hex, drop the first two char so that it is only a 6 char hex, and convert back to an integer

I have been searching and experimenting for many, many, hours now, and so far I have not been able to adapt any of the solutions I have come across to do what I want.
My goal is to take an integer (538214658) and convert it into an 8 character hex string (020148102). Then I want to drop the first two characters (0148102) and convert it back into an integer(1343746) which I am using as a key in a map array.
The solutions I've seen so far just convert an integer into hex string, but don't take into account the desired digit length.
I am able to print out just the first 6 characters using the following code:
Console_Print("%06X", form ? form->refID : 0)
So I thought that maybe I could use that technique to store it into a string, and then use iostream or sstream to convert it back to an integer, but none of my searches turned up anything I could use. And all of my experiments have failed.
Some help would be greatly appreciated.
EDIT: Below is my solution based on Klaus' suggestion:
uint32_t GetCoreRefID(TESForm* form)
{
uint32_t iCoreRefID = 0;
if (form)
{
uint32_t iRefID = (uint32_t)(form->refID);
iCoreRefID = iRefID & 0x00ffffff;
}
return iCoreRefID;
}
There is no need to convert to a string representation.
Look the following example:
int main()
{
uint32_t val = 538214658 & 0x00ffffff;
std::cout << std::hex << val << std::endl;
std::cout << std::dec << val << std::endl;
}
You have to learn that a value is still only a value and is not dependent on the representation like decimal or hex. The value stored in a memory area or a register is still the same.
As you can see in the given example I wrote your decimal value representation and remove the first two hexadecimal digits simply by do a bitwise and operation with the hexadecimal representation of a mask.
Furthermore you have to understand that the printing with cout in two different "modes" did not change the value at all and also not the internal representation. With std::dec and std::hex you tell the ostream object how to create a string from an int representation.

How to save hex value from string in uint8_t or char without converting the value?

I have a binary file which I am reading and saving as hex values. These hex values will be used to flash a device, but I need the hex values to be stored as either uint8_t or char (preferably uint8_t). Currently the values are stored in a string, and only one byte at a time. What I want to do is to store the value as uint8_t instead of string.
So if the value of std:string result is 0x3A, I want the value of uint8_t flash[1] to be 0x3A, and not 58 or some other value.
How can this be achieved?
Any help is appreciated :)
EDIT:
As I first expected, and has been confirmed, the values are the same whichever method I am using.
For those who wish to see the code generating the string, here it is:
unsigned char x;
std::ifstream input(file, std::ios::binary);
input >> std::noskipws;
std::stringstream stream, str;
stream << std::hex << std::setw(2) << std::setfill('0') << (int)x;
std::string result( stream.str() );
str << result;
int value;
str >> std::hex >> value;
uint8_t data = value;
In order to fully understand what you are saying we really need to see the code that puts data into your std:string result.
However this may be of help:
std::string result;
result += 58; // this is the same as
result += 0x3A; // this
The compiler assumes the first append is a decimal number because it does not begin with a 0 and converts it from decimal to binary before appending it to the string.
The compiler assumes the second append is a hexadecimal number because it begins with 0x and converts it from hexadecimal to binary before appending it to the string.
In both cases the same binary number is appended to the string.
Now to put that into your array we can do:
uint8_t flash[2]; // big enough to our 2 chars
flash[0] = result[0]; // copy first value
flash[1] = result[1]; // copy second value
Voila!, all done.
0x3A IS 58. They're represented the same in binary and mean exactly the same thing - the only difference is the formatting when output to the user (integers, by default, are output in base 10).
If you're trying to represent 58 as 0x3A in the output stream, just change the way you're outputting it.
A value is a value, 0x3A == 58. There is no difference, is if you put it in an uint8_t is is exactly the same. There is nothing like storing it as 58 or storing it as 0x3A. It both ends up as: 00111010.
You can use the strtol function to convert a hexstring to uint8_t and use 16 as your base number.