I'm working with VS 2010 on Windows. I have a function which takes a char pointer. Now, inside the function, I am calling std::hex to convert it to decimal, but for some reason it is not working. It is outputting a large value which makes me think that it is converting the address instead.
void convertHexToDec(char* hex, char * dec)
{
long long decimal;
std::stringstream ss;
ss << hex;
ss >> std::hex >> decimal;
sprintf (dec, "%llu", decimal);
}
So, if the pass in a char pointer containing "58", the output decimal value is something like 1D34E78xxxxxxxxx. Looks like it is converting the address of the hex.
I tried these ways too:
ss << *hex;
ss << (char*)hex[0];
ss << (int *)&hex[0];
None of the above worked.
Any idea how I can make this function work?
The reason for your error is, probably, the wrong printf specifier. Also, sprintf is not safe: it assumes the destination buffer (dec) is large enough.
A possible solution using your function signature - not recommended since you do not know the size of the destination:
void convertHexToDec( char* hex, char * dec )
{
std::sprintf( dec, "%lld", std::strtoll( hex, 0, 16 ) );
}
A safe solution:
std::string convertHexToDec( const char* h )
{
return std::to_string( std::strtoll( h, 0, 16 ) );
}
A safe solution using streams:
std::string convertHexToDec( const char* h )
{
long long lld;
std::istringstream( h ) >> std::hex >> lld;
std::ostringstream os;
os << lld;
return os.str();
}
Apart from you not using std::string and refrences, I tried the following code:
#include <iostream>
#include <sstream>
void convertHexToDec(char* hex, char* dec)
{
long long decimal;
std::stringstream ss;
ss << hex;
ss >> std::hex >> decimal;
std::cout << "Decimal: " << decimal << "\n";
sprintf (dec, "%llu", decimal);
}
int main()
{
char hex[] = "58";
char dec[4];
convertHexToDec(hex, dec);
std::cout << "Output string: " << dec << "\n";
}
Output:
Decimal: 88
Output string: 88
live example
So what's your problem?
Related
Below code takes a hex string(every byte is represented as its corresponidng hex value)
converts it to unsigned char * buffer and then converts back to hex string.
This code is testing the conversion from unsigned char* buffer to hex string
which I need to send over the network to a receiver process.
I chose hex string as unsigned char can be in range of 0 to 255 and there is no printable character after 127.
The below code just tells the portion that bugs me. Its in the comment.
#include <iostream>
#include <sstream>
#include <iomanip>
using namespace std;
// converts a hexstring to corresponding integer. i.e "c0" - > 192
int convertHexStringToInt(const string & hexString)
{
stringstream geek;
int x=0;
geek << std::hex << hexString;
geek >> x;
return x;
}
// converts a complete hexstring to unsigned char * buffer
void convertHexStringToUnsignedCharBuffer(string hexString, unsigned char*
hexBuffer)
{
int i=0;
while(hexString.length())
{
string hexStringPart = hexString.substr(0,2);
hexString = hexString.substr(2);
int hexStringOneByte = convertHexStringToInt (hexStringPart);
hexBuffer[i] = static_cast<unsigned char>((hexStringOneByte & 0xFF)) ;
i++;
}
}
int main()
{
//below hex string is a hex representation of a unsigned char * buffer.
//this is generated by an excryption algorithm in unsigned char* format
//I am converting it to hex string to make it printable for verification pupose.
//and takes the hexstring as inpuit here to test the conversion logic.
string inputHexString = "552027e33844dd7b71676b963c0b8e20";
string outputHexString;
stringstream geek;
unsigned char * hexBuffer = new unsigned char[inputHexString.length()/2];
convertHexStringToUnsignedCharBuffer(inputHexString, hexBuffer);
for (int i=0;i<inputHexString.length()/2;i++)
{
geek <<std::hex << std::setw(2) << std::setfill('0')<<(0xFF&hexBuffer[i]); // this works
//geek <<std::hex << std::setw(2) << std::setfill('0')<<(hexBuffer[i]); -- > this does not work
// I am not able to figure out why I need to do the bit wise and operation with unsigned char "0xFF&hexBuffer[i]"
// without this the conversion does not work for individual bytes having ascii values more than 127.
}
geek >> outputHexString;
cout << "input hex string: " << inputHexString<<endl;
cout << "output hex string: " << outputHexString<<endl;
if(0 == inputHexString.compare(outputHexString))
cout<<"hex encoding successful"<<endl;
else
cout<<"hex encoding failed"<<endl;
if(NULL != hexBuffer)
delete[] hexBuffer;
return 0;
}
// output
// can some one explain ? I am sure its something silly that I am missing.
the C++20 way:
unsigned char* data = new unsigned char[]{ "Hello world\n\t\r\0" };
std::size_t data_size = sizeof("Hello world\n\t\r\0") - 1;
auto sp = std::span(data, data_size );
std::transform( sp.begin(), sp.end(),
std::ostream_iterator<std::string>(std::cout),
[](unsigned char c) -> std::string {
return std::format("{:02X}", int(c));
});
or if you want to store result into string:
std::string result{};
result.reserve(size * 2 + 1);
std::transform( sp.begin(), sp.end(),
std::back_inserter(result),
[](unsigned char c) -> std::string {
return std::format("{:02X}", int(c));
});
Output:
48656C6C6F20776F726C640A090D00
The output of an unsigned char is like the output of a char which obviously does not what the OP expects.
I tested the following on coliru:
#include <iomanip>
#include <iostream>
int main()
{
std::cout << "Output of (unsigned char)0xc0: "
<< std::hex << std::setw(2) << std::setfill('0') << (unsigned char)0xc0 << '\n';
return 0;
}
and got:
Output of (unsigned char)0xc0: 0�
This is caused by the std::ostream::operator<<() which is chosen out of the available operators. I looked on cppreference
operator<<(std::basic_ostream) and
std::basic_ostream::operator<<
and found
template< class Traits >
basic_ostream<char,Traits>& operator<<( basic_ostream<char,Traits>& os,
unsigned char ch );
in the former (with a little bit help from M.M).
The OP suggested a fix: bit-wise And with 0xff which seemed to work. Checking this in coliru.com:
#include <iomanip>
#include <iostream>
int main()
{
std::cout << "Output of (unsigned char)0xc0: "
<< std::hex << std::setw(2) << std::setfill('0') << (0xff & (unsigned char)0xc0) << '\n';
return 0;
}
Output:
Output of (unsigned char)0xc0: c0
Really, this seems to work. Why?
0xff is an int constant (stricly speaking: an integer literal) and has type int. Hence, the bit-wise And promotes (unsigned char)0xc0 to int as well, yields the result of type int, and hence, the std::ostream::operator<< for int is applied.
This is an option to solve this. I can provide another one – just converting the unsigned char to unsigned.
Where the promotion of unsigned char to int introduces a possible sign-bit extension (which is undesired in this case), this doesn't happen when unsigned char is converted to unsigned. The output stream operator for unsigned provides the intended output as well:
#include <iomanip>
#include <iostream>
int main()
{
std::cout << "Output of (unsigned char)0xc0: "
<< std::hex << std::setw(2) << std::setfill('0') << (unsigned)(unsigned char)0xc0 << '\n';
const unsigned char c = 0xc0;
std::cout << "Output of unsigned char c = 0xc0: "
<< std::hex << std::setw(2) << std::setfill('0') << (unsigned)c << '\n';
return 0;
}
Output:
Output of (unsigned char)0xc0: c0
Output of unsigned char c = 0xc0: c0
Live Demo on coliru
I have a function that accepts a few integer params, and needs to convert then to ASCII string representation of a fixed length of 4. i.e. 4 becomes "0004" and 42 becomes "0042". It is safe to assume the params will be 0<=n<=9999
I could do that with something like:
void foo(int a, int b) {
std::string sa = std::to_string(a);
std::string sb = std::to_string(b);
for(int i = sa.length; i < 4; i++)
sa.insert(0,"0");
...
}
But that seems like more than I should need, especially if there are a lot of params to convert. is there a more efficient way to do this?
Edit: the goal is not to print the resulting strings.
Edit 2: something based around ss << std::setw( 4 ) << std::setfill( '0' ) << number; does what I need, thank you for the comments.
You can use std::ostringstream and treat it like an output stream:
std::ostringstream ss;
ss << std::setw( 4 ) << std::setfill( '0' ) << number;
Send_To_Serial(ss.str().c_str());
I think snprintf is a good candidate:
#include <cstdio>
#include <iostream>
int main() {
char buffer[5];
// Prints: 0001
snprintf(buffer, 5, "%04d", 1);
std::cout << buffer << '\n';
// Prints: 1234 (not the 5)
snprintf(buffer, 5, "%04d", 12345);
std::cout << buffer << '\n';
}
I have a struct that stores the integer value as a custom string type.
typedef char OneLine[MAX_LINE + 1];
So I have some instances where I want the string that contains "12" to be converted to
C.
OneLine testString;
strcpy(testString, "12");
I'd like a way for me to convert testString to be "C"
How should I tackle this?
Thanks in advance.
You can use sscanf to convert "12" to an integer 12. Then you can use sprintf with %x format to convert integer 12 to "C"
The conversion can be done using stringstreams
#include <iostream>
#include <sstream>
#include <string>
#include <ios>
int main()
{
char const *str = "12";
std::istringstream iss( str );
int val;
if( !( iss >> val ) ) {
// handle error
}
std::ostringstream oss;
oss << std::hex << val;
std::cout << oss.str() << std::endl;
}
Or slightly less verbose way with C++11
char const *str = "12";
auto val = std::stoi( str );
std::ostringstream oss;
oss << std::hex << val;
std::cout << oss.str() << std::endl;
First, even if you were to do this manually, you shouldn't use char arrays for strings. Use std::[w]string.
Second, you can do this with std::[w][i|o]stringstream:
istringstream iss("12");
int number;
iss >> number;
ostringstream oss;
oss << hex << number;
const string& hexNumber = oss.str();
// hexNumber now contains "C"
I have the following string: s="80". I need to put this in an
unsigned char k[]. The unsigned char should look like this: unsigned char k[]={0x38,0x34}, where 0x38=8 and 0x34=0 These are the hexadecimal values for 8 and 0. How to do this? Need some help!
Please give some code. Thx
I am working on ubuntu c++ code. THX!
I use this for an encryption! I need 0x38 in an unsigned char.PLEASE HELP! Need some code:)
EDIT:
HOW TO OBTAIN THE DEC/CHAR VALUE AND PUT IT IN AN unsigned char k[]?
I've realised that it's ok if in the unsigned char [] i have the dec values {56,52} of the 8 and 0 that i have in the string!
Assuming you want this string converted as ASCII (or UTF-8) it is already in the correct format.
std::string s="80";
std::cout << "0x" << std::hex << static_cast<int>(s[0]) << "\n";
std::cout << "0x" << std::hex << static_cast<int>(s[1]) << "\n";
If you want it in an int array, then just copy it:
int data[2];
std::copy(s.begin(), s.end(), data);
I think that no matter you store '8' or 0x39, they will be present as the same binary numbers by the computer.
I think you do not really understand what you are asking.
The following are synonyms:
std::string s = "\x38\x30";
std::string s = "80";
As the following are synonyms:
char c = '8', s = '0' ;
char c = s[0], s = s[1];
char c = 0x38, s = 0x30;
It is exactly the same (except if your base encoding is not ASCII). This is not an encryption.
std::string s = "80";
unsigned char * pArray = new unsigned char[ s.size() ];
const char * p = s.c_str();
unsigned char * p2 = pArray;
while( *p )
*p2++ = *p++;
delete []pArray;
You can try it. I did not write these codes. I found I like you
#include <algorithm>
#include <sstream>
#include <iostream>
#include <iterator>
#include <iomanip>
namespace {
const std::string test="mahmutefe";
}
int main() {
std::ostringstream result;
result << std::setw(2) << std::setfill('0') << std::hex << std::uppercase;
std::copy(test.begin(), test.end(), std::ostream_iterator<unsigned int>(result, " "));
std::cout << test << ":" << result.str() << std::endl;
system("PAUSE");
}
convert that string to a char array, then subrtact '0' from each char.
I have tried to find this topic on the web but I couldn't find the one I need.
I have a string of character:
char * tempBuf = "qj";
The result I want is 0x716A, and that value is going to be converted into decimal value.
Is there any function in vc++ that can be used for that?
You can use a stringstream to convert each character to a hexadecimal representation.
#include <iostream>
#include <sstream>
#include <cstring>
int main()
{
const char* tempBuf = "qj";
std::stringstream ss;
const char* it = tempBuf;
const char* end = tempBuf + std::strlen(tempBuf);
for (; it != end; ++it)
ss << std::hex << unsigned(*it);
unsigned result;
ss >> result;
std::cout << "Hex value: " << std::hex << result << std::endl;
std::cout << "Decimal value: " << std::dec << result << std::endl;
}
So if I understood correctly the idea...
#include <stdint.h>
uint32_t charToUInt32(const char* src) {
uint32_t ret = 0;
char* dst = (char*)&ret;
for(int i = 0; (i < 4) && (*src); ++i, ++src)
dst[i] = *src;
return ret;
}
If I understand what you want correctly: just loop over the characters, start to finish; at each character, multiply the sum so far by 256, and add the value of the next character; that gives the decimal value in one shot.
What you are looking for is called "hex encoding". There are a lot of libraries out there that can do that (unless what you were looking for was how to implement one yourself).
One example is crypto++.