unsigned char* to double in c++ - c++

I am copying double value into unsigned char* in the following way.
unsigned char* cmdBody;
double val = (double)-1;
std::ostringstream sstream;
sstream << val;
std::string valString = sstream.str();
unsigned int dataSize = valString.size() + 1;
cmdBody = (unsigned char*)malloc(dataSize);
memset(cmdBody, 0, dataSize);
memcpy(cmdBody, (unsigned char*)valString.c_str(), dataSize - 1);
cmdBody[dataSize - 1] = '\0';
From cmdBody I need to convert the value into double type. How to do it?

C much?
Your solution is very simple if you just use a std::string:
const auto val = -1.0; // Input double
const auto cmdBody = std::to_string(val); // Convert double to a std::string
const auto foo = std::stod(cmdBody); // Convert std::string to a double
It's important to note that there is no need to allocate, memcopy, or null-terminate when constructing a std::string. Which vastly simplifies your code.

Use std::stod, something like this:
#include <string>
double d = std::stod(cmdBody);

std::istringstream istream(std::string("3.14"));
double d;
istream >> d;
if (!istream.fail())
{
// convertion ok
}

Related

Conversion from hexadecimal string to double in C++

I have a string in byte that represent a double number. It is like this in hexadecimal format:
char buffer[17] = "4053E60C49BA5E35";
In double the correct value is: 21,898625.
I need a simple way to convert this string in double. The only way that work just now is this, but I'm not sure it this the best way:
double hexstr2double(const std::string& hexstr)
{
union
{
long long i;
double d;
} value;
try{
value.i = std::stoll(hexstr, nullptr, 16);
}
catch(...){value.i=0;}
return value.d;
}
Thank you
You can use reinterpret_cast instead of the union.
Also the value you presented is different on a site for conversion from hex to double: https://gregstoll.com/~gregstoll/floattohex/
#include <iostream>
using namespace std;
double hexstr2double(const std::string& hexstr)
{
double d = 0.0;
try{
*reinterpret_cast<unsigned long long*>(&d) = std::stoull(hexstr, nullptr, 16);
}
catch(...){}
return d;
}
int main()
{
char buffer[] = "4035e60c49ba5e35";
cout<<sizeof(double)<<" "<<sizeof(unsigned long long)<<endl;
cout<<hexstr2double(buffer);
return 0;
}

Addition string to avoid number limitation

I want to add two numbers by adding number by number like when you are child.
In order to calculate very long numbers (more than the C++ limitation).
My first step is to try an example 2 numbers having a sum < 10:
string valeur1 = "135";
string valeur2 = "844";
string result;
for (int i = 0; i < valeur1.length(); i++)
{
std::ostringstream ss;
int value;
int value3;
int value2;
//string to int
valeur1[i] >> value;
valeur2[i] >> value2;
value3 = (value + value2);
// int to string
ss << value3;
result = result + ss.str();
}
cout << result;
Am I headed in the right direction?
I think you are headed in the right direction. Three things you can improve:
You have to take into account when value3 is larger than 10 (You seem aware of that)
Be careful when the two numbers don't have the same number of digits. Now your code will fail in that case.
You are using an array of characters. Why not use an array of integers instead? If you only want to avoid the size limitation of an integer I think it would be a much better option as you wouldn't need all the string<->integer conversions.
Your first step is very simple:
#include <string>
#include <iostream>
int main()
{
std::string s1 = "135";
std::string s2 = "844";
std::string result;
for(size_t i=0;i<std::min(s1.size(),s2.size());i++)
result+= std::to_string(s1[i]-'0'+s2[i]-'0');
std::cout<<result<<std::endl;
return 0;
}
Edit:
As noted Gerard Abello , you should take into account the different size of strings and case when sum is greater than 3. However,I believe that the string representation is a good option. One of the options for adding the numbers as strings.
# include <string>
# include <iostream>
std::pair<int,std::string> simpleConvert(const std::string &str);
std::string add(const std::string &first,const std::string &second);
int main()
{
std::string s1 = "128";
std::string s2 = "9999";
std::string result = add(s1,s2);
std::cout<<result<<std::endl;
return 0;
}
std::pair<int,std::string> simpleConvert(const std::string &str)
{
if(str.size()==1)
return std::make_pair(0,str);
else if(str.size()==2)
return std::make_pair(str[0]-'0',std::string(str.begin()+1,str.end()));
}
std::string add(const std::string &first,const std::string &second)
{
std::string s1(first.rbegin(),first.rend());
std::string s2(second.rbegin(),second.rend());
auto n = s1.size();
auto m = s2.size();
auto min = std::min(n,m);
auto max = std::max(n,m);
for(size_t j=min;j!=max;j++)
if(n<m)
s1+="0";
else
s2+="0";
std::string result;
int add=0;
for(size_t i=0;i<s1.size();i++)
{
auto temp = simpleConvert(std::to_string(s1[i]-'0'+s2[i]-'0'+add));
result+= temp.second;
add = temp.first;
}
if(add!=0)
result+=std::to_string(add);
return std::string(result.rbegin(),result.rend());
}

How to Convert integer to char array

int x = 1231212;
memcpy(pDVal, &x, 4);
int iDSize = sizeof(double);
int i = 0;
for (; i<iDSize; i++)
{
char c;
memcpy(&c, &(pDVal[i]), 1);
printf("%d|\n", c);
printf("%x|\n", c);
}
I used above code segment to print the hex value of each byte of a Integer. But that is not working properly. What is issue here ?
Try something like this:
void Int32ToUInt8Arr( int32 val, uint8 *pBytes )
{
pBytes[0] = (uint8)val;
pBytes[1] = (uint8)(val >> 8);
pBytes[2] = (uint8)(val >> 16);
pBytes[3] = (uint8)(val >> 24);
}
or perhaps:
UInt32 arg = 18;
array<Byte>^byteArray = BitConverter::GetBytes( arg);
// {0x12, 0x00, 0x00, 0x00 }
byteArray->Reverse(byteArray);
// { 0x00, 0x00, 0x00, 0x12 }
for the second example see: http://msdn2.microsoft.com/en-us/library/de8fssa4(VS.80).aspx
Hope this helps.
Just use the sprintf function. You will get a char*, so you have your array.
See the example on the webpage
Your code looks awful. That's it.
memcpy(pDVal, &x, 4);
What is pDVal? Why do you use 4? Is it sizeof(int)?
int iDSize = sizeof(double);
Why sizeof(double)? May be you need sizeof(int).
memcpy(&c, &(pDVal[i]), 1); makes copy first byte of i-th array pDVal element.
printf("%d|\n", c); is not working because "%d" is waiting integer.
Print like this:
printf("%d|\n", c & 0xff);
printf("%x|\n", c & 0xff);
If you are serious about the c++, this is how I would suggest to do it.
#include <sstream>
template <typename Int>
std::string intToStr(Int const i) {
std::stringstream stream;
stream << std::hex << i;
return stream.str();
}
Which you may invoke as intToStr(1231212). If you insist on getting a char array (I strongly suggest you use std::string), you can copy the c_str() result over:
std::string const str = intToStr(1231212);
char* const chrs = new char[str.length()+1];
strcpy(chrs,str.c_str()); // needs <string.h>

Convert long to char* const

What is the right way to convert long to char* const in C++?
EDIT:
long l = pthread_self();
ThirdPartyFunction("Thread_Id_"+l); //Need to do this
ThirdPartyFunction(char* const identifierString)
{}
EDIT:
The "proper" way to convert an integer to a string, in C++, is to use a stringstream. For instance:
#include <sstream>
std::ostringstream oss;
ossĀ << "Thread_Id_" << l;
ThirdPartyFunction(oss.str().c_str());
Now, that probably won't be the "fastest" way (streams have some overhead), but it's simple, readable, and more importantly, safe.
OLD ANSWER BELOW
Depends on what you mean by "convert".
To convert the long's contents to a pointer:
char * const p = reinterpret_cast<char * const>(your_long);
To "see" the long as an array of chars:
char * const p = reinterpret_cast<char * const>(&your_long);
To convert the long to a string:
std::ostringstream oss;
oss << your_long;
std::string str = oss.str();
// optionaly:
char * const p = str.c_str();
Another possibile "pure" solution is to use snprintf
long number = 322323l;
char buffer [128];
int ret = snprintf(buffer, sizeof(buffer), "%ld", number);
char * num_string = buffer; //String terminator is added by snprintf
long l=0x7fff0000; // or whatever
char const *p = reinterpret_cast<char const *>(l);

How to convert from const char* to unsigned int c++

I am new in c++ programming and I have been trying to convert from const char* to unsigned int with no luck.
I have a:
const char* charVar;
and i need to convert it to:
unsigned int uintVar;
How can it be done in C++?
Thanks
#include <iostream>
#include <sstream>
const char* value = "1234567";
stringstream strValue;
strValue << value;
unsigned int intValue;
strValue >> intValue;
cout << value << endl;
cout << intValue << endl;
Output:
1234567
1234567
What do you mean by convert?
If you are talking about reading an integer from the text, then you have several options.
Boost lexical cast: http://www.boost.org/doc/libs/1_44_0/libs/conversion/lexical_cast.htm
String stream:
const char* x = "10";
int y;
stringstream s(x);
s >> y;
Or good old C functions atoi() and strtol()
If you really want to convert a pointer to a constant character into an unsigned int then you should use in c++:
const char* p;
unsigned int i = reinterpret_cast<unsigned int>( p );
This converts the address to which the pointer points to into an unsigned integer.
If you want to convert the content to which the pointer points to into an unsigned int you should use:
const char* p;
unsigned int i = static_cast<unsigned int>( *p );
If you want to get an integer from a string, and hence interpret the const char* as a pointer to a const char array, you can use one of the solutions mentioned above.
The C way:
#include <stdlib.h>
int main() {
const char *charVar = "16";
unsigned int uintVar = 0;
uintVar = atoi(charVar);
return 0;
}
The C++ way:
#include <sstream>
int main() {
istringstream myStream("16");
unsigned int uintVar = 0;
myStream >> uintVar;
return 0;
}
Notice that in neither case did I check the return code of the conversion to make sure it actually worked.
In C this can be done using atoi which is also available to C++ via cstdlib.
I usually use this generic function to convert a string into "anything":
#include <sstream>
// Convert string values into type T results.
// Returns false in case the conversion fails.
template <typename T>
bool getValueFromString( const std::string & value, T & result )
{
std::istringstream iss( value );
return !( iss >> result ).fail();
}
just use it as in:
int main()
{
const char * a_string = "44";
unsigned int an_int;
bool success;
// convert from const char * into unsigned int
success = getValueFromString( a_string, an_int );
// or any other generic convertion
double a;
int b;
float c;
// conver to into double
success = getValueFromString( "45", a );
// conve rto into int
success = getValueFromString( "46", b );
// conver to into float
success = getValueFromString( "47.8", c );
}
atoi function will convert const char* to int, which can be implicitly converted to unsigned. This won't work for large integers that don't fit in int.
A more C++-ish way is to use strings and streams
#include <sstream>
#include <string>
int main()
{
std::string strVar;
unsigned uintVar;
std::istringstream in(strVar);
in >> uintVar;
}
An easier but nonstandard way would be to use boost's lexical cast.
HTH
So I know this is old but thought I would provide a more efficient way of doing this that will give you some flexibility on what you want as a base is.
#include<iostream>
unsigned long cstring_to_ul(const char* str, char** end = nullptr, int base = 10)
{
errno = 0; // Used to see if there was success or failure
auto ul = strtoul(str, end, base);
if(errno != ERANGE)
{
return ul;
}
return ULONG_MAX;
}
What this will do is create a wrapper around the method strtoul(const char* nptr, char** endptr, int base) method from C. For more information on this function you can read the description from the man page here https://linux.die.net/man/3/strtoul
Upon failure you will have errno = ERANGE, which will allow you to do a check after calling this function along with the value being ULONG_MAX.
An example of using this can be as follows:
int main()
{
unsigned long ul = cstring_to_ul("3284201");
if(errno == ERANGE && ul == ULONG_MAX)
{
std::cout << "Input out of range of unsigned long.\n";
exit(EXIT_FAILURE);
}
std::cout << "Output: " << ul << "\n";
}
This will give the output
Output: 3284201
Try in this way
#include<iostream>
#include <typeinfo> //includes typeid
using namespace std;
int main(){
char a = '3';
int k = 3;
const char* ptr = &a;
cout << typeid(*ptr).name() << endl; //prints the data type c = char
cout << typeid(*ptr-'0').name() << endl; //prints the data type i = integer
cout << *ptr-'0' << endl;
return 0;
}
Without more information there is no way to properly answer this question. What are you trying to convert exactly? If charVar is an ascii representation of the string, then you can do like others have suggested and use stringstreams, atoi, sscanf, etc.
If you want the actual value pointed to by charVar, then instead you'd want something like:
intValue = (unsigned int)(*charVal);
Or if charVal is the pointer to the first byte of an unsigned integer then:
intValue = *((unsigned int*)(charVal));
const char* charVar = "12345";
unsigned int uintVar;
try {
uintVar = std::stoi( std::string(charVar) );
}
catch(const std::invalid_argument& e) {
std::cout << "Invalid Arg: " << e.what() << endl;
}
catch(const std::out_of_range& e) {
std::cout << "Out of range: " << e.what() << endl;
}
You can also use strtoul or _tcstoul to get unsigned long value from const char* and then cast the value to unsigned int.
http://msdn.microsoft.com/en-us/library/5k9xb7x1(v=vs.71).aspx
const char* charVar = "1864056953";
unsigned int uintVar = 0;
for (const char* it = charVar; *it != 0; *it++){
if ((*it < 48) || (*it > 57)) break; // see ASCII table
uintVar *= 10; // overflow may occur
uintVar += *it - 48; //
}
std::cout << uintVar << std::endl;
std::cout << charVar << std::endl;