Hello I have variable like this:
uint8_t *str value = "100663296";
I just wan't to convert to hexadecimal interpretation of str.
I doesn't need any math operations on this variable.
uint8_t *output value = "6000000";
How to do it correctly? I can't use convert to int and use sprintf because i don't have memmory for this on my MCU.
UPDATE: missed the part about MCU and memory limitations :) this answer won't be useful
You can try to do the following:
convert your string representation of the number to integer value (you can use int atoi( const char * str ); function
once you have your integer you can print it as HEX using, for example, sprintf function with %x as a format parameter and you integer as a value parameter
Here is a working example: https://ideone.com/axAPWH
#include <iostream>
using namespace std;
int main() {
int n;
char hex_val[50];
n = atoi("100663296");
sprintf(hex_val, "%x", n);
cout << hex_val;
return 0;
}
Could use <charconv> if available:
#include <charconv>
#include <cstdio>
#include <cstdlib>
int main() {
auto const* str = "2147483647";
errno = 0;
char* end;
long i = std::strtol(str, &end, 10);
if (end == str || errno == ERANGE)
return 1;
char out[20];
auto const [p, err] = std::to_chars(out, out + sizeof out, i, 16);
if (err != std::errc{})
return 2;
*p = 0; // null terminate
std::puts(out);
}
Related
I am trying to convert some C++ code to C for my compiler that can't run with C++ code. I'd like to create the template below to C. This template converts the decimal integer to hexadecimal, and adds 0 in front of value if the size of the hexadecimal string is smaller than (sizeof(T)*2). Data type T can be unsigned char, char, short, unsigned short, int, unsigned int, long long, and unsigned long long.
template< typename T > std::string hexify(T i)
{
std::stringbuf buf;
std::ostream os(&buf);
os << std::setfill('0') << std::setw(sizeof(T) * 2)
<< std::hex << i;
std::cout<<"sizeof(T) * 2 = "<<sizeof(T) * 2<<" buf.str() = "<<buf.str()<<" buf.str.c_str() = "<<buf.str().c_str()<<std::endl;
return buf.str().c_str();
}
Thank you for tour help.
Edit 1: I have tried to use the declaration
char * hexify (void data, size_t data_size)
but when I call with the int value int_value:
char * result = hexify(int_value, sizeof(int))
it doesn't work because of:
noncompetitive type (void and int).
So in this case, do I have to use a macro? I haven't tried with macro because it's complicated.
C does not have templates. One solution is to pass the maximum width integer supported (uintmax_t, in Value below) and the size of the original integer (in Size). One routine can use the size to determine the number of digits to print. Another complication is C does not provide C++’s std::string with is automatic memory management. A typical way to handle this in C is for the called function to allocate a buffer and return it to the caller, who is responsible for freeing it when done.
The code below shows a hexify function that does this, and it also shows a Hexify macro that takes a single parameter and passes both its size and its value to the hexify function.
Note that, in C, character constants such as 'A' have type int, not char, so some care is needed in providing the desired size. The code below includes an example for that.
#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
char *hexify(size_t Size, uintmax_t Value)
{
// Allocate space for "0x", 2*Size digits, and a null character.
size_t BufferSize = 2 + 2*Size + 1;
char *Buffer = malloc(BufferSize);
// Ensure a buffer was allocated.
if (!Buffer)
{
fprintf(stderr,
"Error, unable to allocate buffer of %zu bytes in %s.\n",
BufferSize, __func__);
exit(EXIT_FAILURE);
}
// Format the value as "0x" followed by 2*Size hexadecimal digits.
snprintf(Buffer, BufferSize, "0x%0*" PRIxMAX, (int) (2*Size), Value);
return Buffer;
}
/* Provide a macro that passes both the size and the value of its parameter
to the hexify function.
*/
#define Hexify(x) (hexify(sizeof (x), (x)))
int main(void)
{
char *Buffer;
/* Show two examples of using the hexify function with different integer
types. (The examples assume ASCII.)
*/
char x = 'A';
Buffer = hexify(sizeof x, x);
printf("Character '%c' = %s.\n", x, Buffer); // Prints "0x41".
free(Buffer);
int i = 123;
Buffer = hexify(sizeof i, i);
printf("Integer %d = %s.\n", i, Buffer); // Prints "0x00007b".
free(Buffer);
/* Show examples of using the Hexify macro, demonstrating that 'A' is an
int value, not a char value, so it would need to be cast if a char is
desired.
*/
Buffer = Hexify('A');
printf("Character '%c' = %s.\n", 'A', Buffer); // Prints "0x00000041".
free(Buffer);
Buffer = Hexify((char) 'A');
printf("Character '%c' = %s.\n", 'A', Buffer); // Prints "0x41".
free(Buffer);
}
You don't need templates if you step down to raw bits and bytes.
If performance is important, it is also best to roll out the conversion routine by hand, since the string handling functions in C and C++ come with lots of slow overhead. The somewhat well-optimized version would look something like this:
char* hexify_data (char*restrict dst, const char*restrict src, size_t size)
{
const char NIBBLE_LOOKUP[0xF+1] = "0123456789ABCDEF";
char* d = dst;
for(size_t i=0; i<size; i++)
{
size_t byte = size - i - 1; // assuming little endian
*d = NIBBLE_LOOKUP[ (src[byte]&0xF0u)>>4 ];
d++;
*d = NIBBLE_LOOKUP[ (src[byte]&0x0Fu)>>0 ];
d++;
}
*d = '\0';
return dst;
}
This breaks down any passed type byte-by-byte, using a character type. Which is fine, when using character types specifically. It also uses caller allocation for maximum performance. (It can also be made endianess-independent with an extra check per loop.)
We can make the call a bit more convenient with a wrapper macro:
#define hexify(buf, var) hexify_data(buf, (char*)&var, sizeof(var))
Full example:
#include <string.h>
#include <stdint.h>
#include <stdio.h>
#define hexify(buf, var) hexify_data(buf, (char*)&var, sizeof(var))
char* hexify_data (char*restrict dst, const char*restrict src, size_t size)
{
const char NIBBLE_LOOKUP[0xF+1] = "0123456789ABCDEF";
char* d = dst;
for(size_t i=0; i<size; i++)
{
size_t byte = size - i - 1; // assuming little endian
*d = NIBBLE_LOOKUP[ (src[byte]&0xF0u)>>4 ];
d++;
*d = NIBBLE_LOOKUP[ (src[byte]&0x0Fu)>>0 ];
d++;
}
*d = '\0';
return dst;
}
int main (void)
{
char buf[50];
int32_t i32a = 0xABCD;
puts(hexify(buf, i32a));
int32_t i32b = 0xAAAABBBB;
puts(hexify(buf, i32b));
char c = 5;
puts(hexify(buf, c));
uint8_t u8 = 100;
puts(hexify(buf, u8));
}
Output:
0000ABCD
AAAABBBB
05
64
an optional solution is to use format string like printf
note that you can't return pointer to local variable, but you can get the buffer as argument, (here it is without boundaries check).
char* hexify(char* result, const char* format, void* arg)
{
int size = 0;
if(0 == strcmp(format,"%d") || 0 == strcmp(format,"%u"))
{
size=4;
sprintf(result,"%08x",arg);
}
else if(0 == strcmp(format,"%hd") || 0 == strcmp(format,"%hu"))
{
size=2;
sprintf(result,"%04x",arg);
}
else if(0 == strcmp(format,"%hhd")|| 0 == strcmp(format,"%hhu"))
{
size=1;
sprintf(result,"%02x",arg);
}
else if(0 == strcmp(format,"%lld") || 0 == strcmp(format,"%llu") )
{
size=8;
sprintf(result,"%016x",arg);
}
//printf("size=%d", size);
return result;
}
int main()
{
char result[256];
printf("%s", hexify(result,"%hhu", 1));
return 0;
}
as we know itoa tries to convert an integer in any base but to char array which has fix size, I am trying to find an alternative which can do the same work but convert to string with base 2 in c++.
You can easily write your own.
void my_itoa(int value, std::string& buf, int base){
int i = 30;
buf = "";
for(; value && i ; --i, value /= base) buf = "0123456789abcdef"[value % base] + buf;
}
This was taken from this website, along with many other alternatives.
For C++11, you can use bitset and to_string.
#include <iostream>
#include <bitset>
using namespace std;
int main() {
// your code goes here
cout << bitset<4>(10).to_string() << endl;
return 0;
}
So I got asked this on a skills test for an internship, and at the time it completely baffled me. I have some code now that I thought should work, but isn't assigning the correct values to the string.
#include <iostream>
#include <string>
using namespace std;
int main()
{
// declarations
int i = 0, num= 63;
string b="";
while (num != 0)
{
i = num % 10;
b.insert(0,i + 48 + "");
num = num/10;
}
cout << b << endl;
return 0;
}
With "num" being the integer value (I just used 63 as an example)
EDIT:: I incorrectly paraphrased, I could not use any function that did an int to string conversion for me, not that I couldn't use the string library, my mistake.
Change the insert line to
b.insert(0, 1, '0' + i);
This will insert the character obtained from adding i to '0' once at index 0 in the string.
Explanation of why your code isn't working:
b.insert(0,i + 48 + "");
the line above is calling
basic_string::insert( size_type index, const CharT* s );
where the pointer is being determined by adding 48 + i to the address of the "" string literal, resulting in garbage.
I would suggest recursive function:
std::string f( int val )
{
if ( val >= 10 )
return f( val / 10 ) + ( char )( val % 10 + '0' ) ;
else
return std::string( 1, '0' + val ) ;
}
Usage:
std::cout << f( 63 ) << std::endl ;
Note that this function should append to your string instead of using very expensive shifting (and putting in the front of the string.)
It is worth noting that there are other errors with the code. For example, the transformation doesn't work for num == 0. Here is a better version:
#include <iostream>
#include <algorithm>
#include <string>
#include <cstdlib>
int main(int ac, char* av[])
{
int num(ac == 1? 0: std::atoi(av[1]));
std::string b;
do
{
b.push_back((num % 10) + '0');
num /= 10;
}
while (num != 0);
std::reverse(b.begin(), b.end());
std::cout << b << '\n';
return 0;
}
Very simple solution: Use string streams. In this case, an output string stream:
#include <iostream>
#include <string>
#include <sstream>
std::string IntToString(int value) {
std::ostringstream ss;
ss << value;
return ss.str();
}
const char* IntToCString(int value) {
std::ostringstream ss;
ss << value;
return ss.str().c_str();
}
Here's some code that doesn't use any libraries and doesn't perform allocations. Instead, the user is expected to provide a buffer that's large enough, and she receives a pointer to the beginning of the result string in return:
char * format(unsigned int n, char * buf, std::size_t len)
{
if (len == 0) return NULL;
char * p = buf + len;
*--buf = 0;
while (n && p > buf)
{
*--buf = '0' + (n % 10);
n /= 10;
}
return n == 0 ? p : NULL;
}
Embedded people might like this especially because the function doesn't do anything outside your control.
Usage:
char buf[100];
char * s = format(12345, buf, sizeof buf);
if (s) { printf("Formatted: %s\n", s); }
_wtoi when can't convert input, so input isn't integer, returns zero. But the same time input can be zero. Is it a way to determine if there was wrong input or zero?
This is C++, you should be using stringstream to do your conversion:
#include <iostream>
#include <sstream>
int main()
{
using namespace std;
string s = "1234";
stringstream ss;
ss << s;
int i;
ss >> i;
if (ss.fail( ))
{
throw someWeirdException;
}
cout << i << endl;
return 0;
}
A cleaner and easier solution exists with boost's lexical_cast:
#include <boost/lexcal_cast.hpp>
// ...
std::string s = "1234";
int i = boost::lexical_cast<int>(s);
If you insist on using C, sscanf can do this cleanly.
const char *s = "1234";
int i = -1;
if(sscanf(s, "%d", &i) == EOF)
{
//error
}
You can also use strtol with the caveat that it requires a little thinking. Yes, it'll return zero for both strings evaluating to zero and for error, but it also has an (optional) parameter endptr which will point to the next character after the numeric that's been converted:
const char *s = "1234";
const char *endPtr;
int i = strtol(s, &endPtr, 10);
if (*endPtr != NULL) {
//error
}
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;