Convert string into hex format and append "0x " to hex value - c++

I need to convert string to hex format and append "0x" prefix to hex value.
For Example:
Input: std::string s = "0x06A4";
Output: int num = 0x06A4
I have tried this code:
{
std::stringstream ss;
std::string s = "0x06A4";
int num = std::stoi(s, 0, 16);
std::cout << "value in decimal = " << num << '\n';
std::cout << "value in hexadecimal = " << std::hex << num << '\n';
ss << "0x" << std::hex << num << '\n'; //
std::string res = ss.str();
std::cout << "result " << res << '\n';
}

#yogita, std::hex is just one of the configuration you need. You are probably missing the setfill and the setw configuration, as following:
#include <iostream>
#include <sstream>
#include <iomanip>
int main()
{
std::stringstream ss;
std::string s = "0x06A4";
int num = std::stoi(s, nullptr, 16);
std::cout << "value in decimal = " << num << '\n';
std::cout << "value in hexadecimal = " << std::hex << num << '\n';
ss << "0x" << std::hex << std::setfill('0') << std::setw(4) <<num << '\n';
std::string res = ss.str();
std::cout << "result " << res << '\n';
return 0;
}

Related

How to log a hex string in c++ with ostringstream?

I'm trying to log hex values to an ostringstream, but it's not working. I'm trying:
unsigned char buf[4];
buf[0] = 0;
buf[1] = 1;
buf[2] = 0xab;
buf[3] = 0xcd;
std::ostringstream e1;
e1 << "0x" << std::setfill('0') << std::setw(3) << std::hex << buf[0] << " " << "0x" << std::setfill('0') << std::setw(3) << std::hex << buf[1] << " " << "0x" << std::setfill('0') << std::setw(3) << std::hex << buf[2] << " " << "0x" << std::setfill('0') << std::setw(3) << std::hex << buf[3];
std::cout << e1.str() << std::endl;
I'm expecting to get something like "0x00 0x01 0xab 0xcd" but instead I get "0x00".
I also tried breaking it up like
e1 << "0x" << std::setfill('0') << std::setw(3) << std::hex << buf[0];
e1 << " ";
e1 << "0x" << std::setfill('0') << std::setw(3) << std::hex << buf[1];
e1 << " ";
e1 << "0x" << std::setfill('0') << std::setw(3) << std::hex << buf[2];
e1 << " ";
e1 << "0x" << std::setfill('0') << std::setw(3) << std::hex << buf[3];
but get the same thing.
I assume, that the mainproblem here is the interpretation of char by your stringstream. Try to cast it to int and everything works like charm:
#include <iostream>
#include <sstream>
#include <iomanip>
using namespace std;
int main()
{
unsigned char buf[4];
buf[0] = 0;
buf[1] = 1;
buf[2] = 0xab;
buf[3] = 0xcd;
ostringstream e1;
for (uint i=0; i< sizeof(buf); ++i)
{
e1 << "0x" << std::setw(2) << std::setfill('0') << std::hex << static_cast<int>(buf[i]) << " ";
}
cout << e1.str() << endl;
return 0;
}
This gives you your desired output:
0x00 0x01 0xab 0xcd
The issue is that the characters are not treated as integers in output stream and so the integer manipulators do not affect their output.
Basically ... replace
unsigned char buf[4];
With
unsigned int buf[4];
This works:
e1 << "0x" << std::setfill('0') << std::setw(2) << std::hex << (int)buf[0]
<< " " << "0x" << std::setfill('0') << std::setw(2) << std::hex << (int)buf[1]
<< " " << "0x" << std::setfill('0') << std::setw(2) << std::hex << (int)buf[2]
<< " " << "0x" << std::setfill('0') << std::setw(2) << std::hex << (int)buf[3];
I've added casts to (int) and change setw(2).

Convert Hexadecimal string to decimal number in C++

I want to convert a hexadecimal string to a decimal number (integer) in C++ and tried with following ways:
std::wstringstream SS;
SS << std::dec << stol(L"0xBAD") << endl;
But it returned 0 instead 2989.
std::wstringstream SS;
SS << std::dec << reinterpret_cast<LONG>(L"0xBAD") << endl;
But it returned -425771592 instead 2989.
But, when I use it like below, it works fine and gives 2989 as expect.
std::wstringstream SS;
SS << std::dec << 0xBAD << endl;
But I want to input a string and get 2989 as output, instead integer input like 0xBAD. For example, I want to input "0xBAD" and cast it to integer and then convert to a decimal number.
Thanks in advance.
// stol example
#include <iostream> // std::cout
#include <string> // std::string, std::stol
int main ()
{
std::string str_dec = "1987520";
std::string str_hex = "2f04e009";
std::string str_bin = "-11101001100100111010";
std::string str_auto = "0x7fffff";
std::string::size_type sz; // alias of size_t
long li_dec = std::stol (str_dec,&sz);
long li_hex = std::stol (str_hex,nullptr,16);
long li_bin = std::stol (str_bin,nullptr,2);
long li_auto = std::stol (str_auto,nullptr,0);
std::cout << str_dec << ": " << li_dec << '\n';
std::cout << str_hex << ": " << li_hex << '\n';
std::cout << str_bin << ": " << li_bin << '\n';
std::cout << str_auto << ": " << li_auto << '\n';
return 0;
}

Generating a new guid string in c++ missing some zeros

I tried using the following code to generate a new guid string of 36 characters, but this sometimes prints only 35 or 34 characters. I suppose this is due to the 'zeros' in the guid, but I am unable to clearly see why. Is there a way I can correct this issue?
#include <string>
#include <sstream>
#include <iostream>
#include <windows.h>
#include <iomanip>
int main()
{
GUID guid;
CoCreateGuid(&guid);
std::ostringstream os;
os.width(8);
os << std::hex << std::setfill('0') << guid.Data1 << '-';
os.width(4);
os << std::hex << std::setfill('0') << guid.Data2 << '-';
os.width(4);
os << std::hex << std::setfill('0') << guid.Data3 << '-';
os.width(2);
os << std::hex << std::setfill('0')
<< static_cast<short>(guid.Data4[0])
<< static_cast<short>(guid.Data4[1])
<< '-'
<< static_cast<short>(guid.Data4[2])
<< static_cast<short>(guid.Data4[3])
<< static_cast<short>(guid.Data4[4])
<< static_cast<short>(guid.Data4[5])
<< static_cast<short>(guid.Data4[6])
<< static_cast<short>(guid.Data4[7]);
std::string s(os.str());
std::cout << s << std::endl;
std::cout << s.length() << std::endl;
}
Sample output:
f6979589-b13c-416d-bf49-1497d99cd88
35
Press any key to continue . . .
You need to directly set field size for any new value you output, like this:
int main()
{
GUID guid;
CoCreateGuid(&guid);
std::ostringstream os;
os.width(8);
os << std::hex << std::setfill('0') << guid.Data1 << '-';
os.width(4);
os << std::hex << std::setfill('0') << guid.Data2 << '-';
os.width(4);
os << std::hex << std::setfill('0') << guid.Data3 << '-';
os.width(2);
os << std::hex << std::setfill('0') << std::setw(2)
<< static_cast<short>(guid.Data4[0]) << std::setw(2)
<< static_cast<short>(guid.Data4[1])
<< '-' << std::setw(2)
<< static_cast<short>(guid.Data4[2]) << std::setw(2)
<< static_cast<short>(guid.Data4[3]) << std::setw(2)
<< static_cast<short>(guid.Data4[4]) << std::setw(2)
<< static_cast<short>(guid.Data4[5]) << std::setw(2)
<< static_cast<short>(guid.Data4[6]) << std::setw(2)
<< static_cast<short>(guid.Data4[7]);
std::string s(os.str());
std::cout << s << std::endl;
std::cout << s.length() << std::endl;
}

Converting hex string to negative double

I'm trying to convert hex strings to double values, where some of the values are negative. This answer works fine for positive double hex strings, but when the double is negative I get a std::out_of_range exception. Why is that? Is there a way to get around it?
I have also tried to do the same thing with stringstream, and that works just fine for both positive and negative hex strings. So there is always that solution, but to me the union approach looks a bit more elegant. A matter of taste I guess.
Sample code:
#include <string>
#include <iostream>
#include <iomanip>
#include <sstream>
int main()
{
std::string str1("3fb999999999999a"); // 0.1
std::string str2("bfb999999999999a"); // -0.1
// ******************************
// UNION
// ******************************
union uint64double
{
unsigned long long i;
double d;
};
uint64double val1;
val1.i = std::stoll(str1, nullptr, 16);
uint64double val2;
val2.i = std::stoll(str2, nullptr, 16); // This throws std::out_of_range exception
const int w = 18;
std::cout << "USING UNION" << std::endl;
std::cout << std::setw(w) << "HEX" << std::setw(w) << "DOUBLE" << std::endl;
std::cout << std::setw(w) << str1 << std::setw(w) << val1.d << std::endl;
std::cout << std::setw(w) << str2 << std::setw(w) << val2.d << std::endl;
std::cout << std::endl;
// ******************************
// STRINGSTREAM
// ******************************
unsigned long long i1;
std::stringstream ss;
ss << std::hex << str1;
ss >> i1;
double d1(reinterpret_cast<double&>(i1));
unsigned long long i2;
ss.clear();
ss << std::hex << str2;
ss >> i2;
double d2(reinterpret_cast<double&>(i2));
std::cout << "USING STRINGSTREAM" << std::endl;
std::cout << std::setw(w) << "HEX" << std::setw(w) << "DOUBLE" << std::endl;
std::cout << std::setw(w) << str1 << std::setw(w) << d1 << std::endl;
std::cout << std::setw(w) << str2 << std::setw(w) << d2 << std::endl;
std::cout << std::endl;
return 0;
}
Output:
USING UNION
HEX DOUBLE
3fb999999999999a 0.1
bfb999999999999a 1.#QNAN
USING STRINGSTREAM
HEX DOUBLE
3fb999999999999a 0.1
bfb999999999999a -0.1
I'm using VS2012
Of course stoll throws std::out_of_range exception on input "bfb999999999999a", because 0xbfb999999999999a > LLONG_MAX. If you use stoull instead, everything works nicely, because 0xbfb999999999999a <= ULLONG_MAX.
You can pass the hex string into the stringstream constructor to clean it up a bit. Your std::hex is in the wrong place. std::hex tells the stream to treat the input as a hex value, rather than just a bunch of characters.
I would put this functionality in its own function too, to make it cleaner:
#include <string>
#include <iostream>
#include <iomanip>
#include <sstream>
double hexToDouble(const std::string& hex)
{
double d = 0;
std::stringstream ss(hex);
ss >> std::hex >> reinterpret_cast<uint64_t&>(d); // I feel dirty
return d;
}
int main()
{
std::string str1("3fb999999999999a"); // 0.1
std::string str2("bfb999999999999a"); // -0.1
std::cout << str1 << ' ' << hexToDouble(str1) << std::endl;
std::cout << str2 << ' ' << hexToDouble(str2) << std::endl;
return 0;
}

Is there a C++ way to format addresses and pointers with iostream?

I have something like
unsigned x = 16;
unsigned* p = &x;
std::cout << std::hex << std::setw(16) << std::setfill('0') << x << std::endl;
std::cout << std::hex << std::setw(16) << std::setfill('0') << p << std::endl;
output:
0000000000000010
000x7fffc35ba784
ostream::operator<< is overloaded for this? I can write this correctly with C, but I was wondering if there is a proper way to do this with iostream.
Use internal like this:
#include <iostream>
#include <iomanip>
int main()
{
unsigned x = 16;
unsigned* p = &x;
std::cout << std::hex << std::setw(16) << std::setfill('0') << x << std::endl;
std::cout << std::hex << std::setw(16) << std::setfill('0') << p << std::endl;
std::cout << std::internal << std::hex << std::setw(16) << std::setfill('0') << p << std::endl;
}
This gives:
0000000000000010
000x7fffd123c1a4
0x007fffd123c1a4