Related
I want to convert a hex string to a 32 bit signed integer in C++.
So, for example, I have the hex string "fffefffe". The binary representation of this is 11111111111111101111111111111110. The signed integer representation of this is: -65538.
How do I do this conversion in C++? This also needs to work for non-negative numbers. For example, the hex string "0000000A", which is 00000000000000000000000000001010 in binary, and 10 in decimal.
use std::stringstream
unsigned int x;
std::stringstream ss;
ss << std::hex << "fffefffe";
ss >> x;
the following example produces -65538 as its result:
#include <sstream>
#include <iostream>
int main() {
unsigned int x;
std::stringstream ss;
ss << std::hex << "fffefffe";
ss >> x;
// output it as a signed type
std::cout << static_cast<int>(x) << std::endl;
}
In the new C++11 standard, there are a few new utility functions which you can make use of! specifically, there is a family of "string to number" functions (http://en.cppreference.com/w/cpp/string/basic_string/stol and http://en.cppreference.com/w/cpp/string/basic_string/stoul). These are essentially thin wrappers around C's string to number conversion functions, but know how to deal with a std::string
So, the simplest answer for newer code would probably look like this:
std::string s = "0xfffefffe";
unsigned int x = std::stoul(s, nullptr, 16);
NOTE: Below is my original answer, which as the edit says is not a complete answer. For a functional solution, stick the code above the line :-).
It appears that since lexical_cast<> is defined to have stream conversion semantics. Sadly, streams don't understand the "0x" notation. So both the boost::lexical_cast and my hand rolled one don't deal well with hex strings. The above solution which manually sets the input stream to hex will handle it just fine.
Boost has some stuff to do this as well, which has some nice error checking capabilities as well. You can use it like this:
try {
unsigned int x = lexical_cast<int>("0x0badc0de");
} catch(bad_lexical_cast &) {
// whatever you want to do...
}
If you don't feel like using boost, here's a light version of lexical cast which does no error checking:
template<typename T2, typename T1>
inline T2 lexical_cast(const T1 &in) {
T2 out;
std::stringstream ss;
ss << in;
ss >> out;
return out;
}
which you can use like this:
// though this needs the 0x prefix so it knows it is hex
unsigned int x = lexical_cast<unsigned int>("0xdeadbeef");
For a method that works with both C and C++, you might want to consider using the standard library function strtol().
#include <cstdlib>
#include <iostream>
using namespace std;
int main() {
string s = "abcd";
char * p;
long n = strtol( s.c_str(), & p, 16 );
if ( * p != 0 ) { //my bad edit was here
cout << "not a number" << endl;
}
else {
cout << n << endl;
}
}
Andy Buchanan, as far as sticking to C++ goes, I liked yours, but I have a few mods:
template <typename ElemT>
struct HexTo {
ElemT value;
operator ElemT() const {return value;}
friend std::istream& operator>>(std::istream& in, HexTo& out) {
in >> std::hex >> out.value;
return in;
}
};
Used like
uint32_t value = boost::lexical_cast<HexTo<uint32_t> >("0x2a");
That way you don't need one impl per int type.
Working example with strtoul will be:
#include <cstdlib>
#include <iostream>
using namespace std;
int main() {
string s = "fffefffe";
char * p;
long n = strtoul( s.c_str(), & p, 16 );
if ( * p != 0 ) {
cout << "not a number" << endl;
} else {
cout << n << endl;
}
}
strtol converts string to long. On my computer numeric_limits<long>::max() gives 0x7fffffff. Obviously that 0xfffefffe is greater than 0x7fffffff. So strtol returns MAX_LONG instead of wanted value. strtoul converts string to unsigned long that's why no overflow in this case.
Ok, strtol is considering input string not as 32-bit signed integer before convertation. Funny sample with strtol:
#include <cstdlib>
#include <iostream>
using namespace std;
int main() {
string s = "-0x10002";
char * p;
long n = strtol( s.c_str(), & p, 16 );
if ( * p != 0 ) {
cout << "not a number" << endl;
} else {
cout << n << endl;
}
}
The code above prints -65538 in console.
Here's a simple and working method I found elsewhere:
string hexString = "7FF";
int hexNumber;
sscanf(hexString.c_str(), "%x", &hexNumber);
Please note that you might prefer using unsigned long integer/long integer, to receive the value.
Another note, the c_str() function just converts the std::string to const char* .
So if you have a const char* ready, just go ahead with using that variable name directly, as shown below [I am also showing the usage of the unsigned long variable for a larger hex number. Do not confuse it with the case of having const char* instead of string]:
const char *hexString = "7FFEA5"; //Just to show the conversion of a bigger hex number
unsigned long hexNumber; //In case your hex number is going to be sufficiently big.
sscanf(hexString, "%x", &hexNumber);
This works just perfectly fine (provided you use appropriate data types per your need).
I had the same problem today, here's how I solved it so I could keep lexical_cast<>
typedef unsigned int uint32;
typedef signed int int32;
class uint32_from_hex // For use with boost::lexical_cast
{
uint32 value;
public:
operator uint32() const { return value; }
friend std::istream& operator>>( std::istream& in, uint32_from_hex& outValue )
{
in >> std::hex >> outValue.value;
}
};
class int32_from_hex // For use with boost::lexical_cast
{
uint32 value;
public:
operator int32() const { return static_cast<int32>( value ); }
friend std::istream& operator>>( std::istream& in, int32_from_hex& outValue )
{
in >> std::hex >> outvalue.value;
}
};
uint32 material0 = lexical_cast<uint32_from_hex>( "0x4ad" );
uint32 material1 = lexical_cast<uint32_from_hex>( "4ad" );
uint32 material2 = lexical_cast<uint32>( "1197" );
int32 materialX = lexical_cast<int32_from_hex>( "0xfffefffe" );
int32 materialY = lexical_cast<int32_from_hex>( "fffefffe" );
// etc...
(Found this page when I was looking for a less sucky way :-)
Cheers,
A.
just use stoi/stol/stoll
for example:
std::cout << std::stol("fffefffe", nullptr, 16) << std::endl;
output: 4294901758
This worked for me:
string string_test = "80123456";
unsigned long x;
signed long val;
std::stringstream ss;
ss << std::hex << string_test;
ss >> x;
// ss >> val; // if I try this val = 0
val = (signed long)x; // However, if I cast the unsigned result I get val = 0x80123456
Try this. This solution is a bit risky. There are no checks. The string must only have hex values and the string length must match the return type size. But no need for extra headers.
char hextob(char ch)
{
if (ch >= '0' && ch <= '9') return ch - '0';
if (ch >= 'A' && ch <= 'F') return ch - 'A' + 10;
if (ch >= 'a' && ch <= 'f') return ch - 'a' + 10;
return 0;
}
template<typename T>
T hextot(char* hex)
{
T value = 0;
for (size_t i = 0; i < sizeof(T)*2; ++i)
value |= hextob(hex[i]) << (8*sizeof(T)-4*(i+1));
return value;
};
Usage:
int main()
{
char str[4] = {'f','f','f','f'};
std::cout << hextot<int16_t>(str) << "\n";
}
Note: the length of the string must be divisible by 2
For those looking to convert number base for unsigned numbers, it is pretty trivial to do yourself in both C/C++ with minimal dependency (only operator not provided by the language itself is pow() function).
In mathematical terms, a positive ordinal number d in base b with n number of digits can be converted to base 10 using:
Example: Converting base 16 number 00f looks like:
= 0*16^2 + 0*16^1 + 16*16^0 = 15
C/C++ Example:
#include <math.h>
unsigned int to_base10(char *d_str, int len, int base)
{
if (len < 1) {
return 0;
}
char d = d_str[0];
// chars 0-9 = 48-57, chars a-f = 97-102
int val = (d > 57) ? d - ('a' - 10) : d - '0';
int result = val * pow(base, (len - 1));
d_str++; // increment pointer
return result + to_base10(d_str, len - 1, base);
}
int main(int argc, char const *argv[])
{
char n[] = "00f"; // base 16 number of len = 3
printf("%d\n", to_base10(n, 3, 16));
}
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);
}
So I am working on a tool that dereferences the values of some addresses, it is in both C and C++, and although I am not familiar with C++ I figured out I can maybe take advantage of the string type offered by C++.
What I have is this:
unsigned char contents_address = 0;
unsigned char * address = (unsigned char *) add.addr;
int i;
for(i = 0; i < bytesize; i++){ //bytesize can be anything from 1 to whatever
if(add.num == 3){
contents_address = *(address + i);
//printf("%02x ", contents_address);
}
}
As you can see what I am trying to do is dereference the unsigned char pointer. What I want to do is have a string variable and concatenate all of the dereferenced values into it and by the end instead of having to go through a for case for getting each one of the elements (by having an array of characters or by just going through the pointers) to have a string variable with everything inside.
NOTE: I need to do this because the string variable is going to a MySQL database and it would be a pain to insert an array into a table...
Try this that I borrowed from this link:
http://www.corsix.org/content/algorithmic-stdstring-creation
#include <sstream>
#include <iomanip>
std::string hexifyChar(int c)
{
std::stringstream ss;
ss << std::hex << std::setw(2) << std::setfill('0') << c;
return ss.str();
}
std::string hexify(const char* base, size_t len)
{
std::stringstream ss;
for(size_t i = 0; i < len; ++i)
ss << hexifyChar(base[i]);
return ss.str();
}
I didn't quite understand what you want to do here (why do you assign a dereferenced value to a variable called ..._address)?.
But maybe what you're looking for is a stringstream.
Here's a relatively efficient version that performs only one allocation and no additional function calls:
#include <string>
std::string hexify(unsigned char buf, unsigned int len)
{
std::string result;
result.reserve(2 * len);
static char const alphabet[] = "0123456789ABCDEF";
for (unsigned int i = 0; i != len)
{
result.push_back(alphabet[buf[i] / 16]);
result.push_back(alphabet[buf[i] % 16]);
{
return result;
}
This should be rather more efficient than using iostreams. You can also modify this trivially to write into a given output buffer, if you prefer a C version which leaves allocation to the consumer.
I would like to generate consecutive C++ strings like e.g. in cameras: IMG001, IMG002 etc. being able to indicate the prefix and the string length.
I have found a solution where I can generate random strings from concrete character set: link
But I cannot find the thing I want to achieve.
A possible solution:
#include <iostream>
#include <string>
#include <sstream>
#include <iomanip>
std::string make_string(const std::string& a_prefix,
size_t a_suffix,
size_t a_max_length)
{
std::ostringstream result;
result << a_prefix <<
std::setfill('0') <<
std::setw(a_max_length - a_prefix.length()) <<
a_suffix;
return result.str();
}
int main()
{
for (size_t i = 0; i < 100; i++)
{
std::cout << make_string("IMG", i, 6) << "\n";
}
return 0;
}
See online demo at http://ideone.com/HZWmtI.
Something like this would work
#include <string>
#include <iomanip>
#include <sstream>
std::string GetNextNumber( int &lastNum )
{
std::stringstream ss;
ss << "IMG";
ss << std::setfill('0') << std::setw(3) << lastNum++;
return ss.str();
}
int main()
{
int x = 1;
std::string s = GetNextNumber( x );
s = GetNextNumber( x );
return 0;
}
You can call GetNextNumber repeatedly with an int reference to generate new image numbers. You can always use sprintf but it won't be the c++ way :)
const int max_size = 7 + 1; // maximum size of the name plus one
char buf[max_size];
for (int i = 0 ; i < 1000; ++i) {
sprintf(buf, "IMG%.04d", i);
printf("The next name is %s\n", buf);
}
char * seq_gen(char * prefix) {
static int counter;
char * result;
sprintf(result, "%s%03d", prefix, counter++);
return result;
}
This would print your prefix with 3 digit padding string. If you want a lengthy string, all you have to do is provide the prefix as much as needed and change the %03d in the above code to whatever length of digit padding you want.
Well, the idea is rather simple. Just store the current number and increment it each time new string is generated. You can implement it to model an iterator to reduce the fluff in using it (you can then use standard algorithms with it). Using Boost.Iterator (it should work with any string type, too):
#include <boost/iterator/iterator_facade.hpp>
#include <sstream>
#include <iomanip>
// can't come up with a better name
template <typename StringT, typename OrdT>
struct ordinal_id_generator : boost::iterator_facade<
ordinal_id_generator<StringT, OrdT>, StringT,
boost::forward_traversal_tag, StringT
> {
ordinal_id_generator(
const StringT& prefix = StringT(),
typename StringT::size_type suffix_length = 5, OrdT initial = 0
) : prefix(prefix), suffix_length(suffix_length), ordinal(initial)
{}
private:
StringT prefix;
typename StringT::size_type suffix_length;
OrdT ordinal;
friend class boost::iterator_core_access;
void increment() {
++ordinal;
}
bool equal(const ordinal_id_generator& other) const {
return (
ordinal == other.ordinal
&& prefix == other.prefix
&& suffix_length == other.suffix_length
);
}
StringT dereference() const {
std::basic_ostringstream<typename StringT::value_type> ss;
ss << prefix << std::setfill('0')
<< std::setw(suffix_length) << ordinal;
return ss.str();
}
};
And example code:
#include <string>
#include <iostream>
#include <iterator>
#include <algorithm>
typedef ordinal_id_generator<std::string, unsigned> generator;
int main() {
std::ostream_iterator<std::string> out(std::cout, "\n");
std::copy_n(generator("IMG"), 5, out);
// can even behave as a range
std::copy(generator("foo", 1, 2), generator("foo", 1, 4), out);
return 0;
}
Take a look at the standard library's string streams. Have an integer that you increment, and insert into the string stream after every increment. To control the string length, there's the concept of fill characters, and the width() member function.
You have many ways of doing that.
The generic one would be to, like the link that you showed, have an array of possible characters. Then after each iteration, you start from right-most character, increment it (that is, change it to the next one in the possible characters list) and if it overflowed, set it to the first one (index 0) and go the one on the left. This is exactly like incrementing a number in base, say 62.
In your specific example, you are better off with creating the string from another string and a number.
If you like *printf, you can write a string with "IMG%04d" and have the parameter go from 0 to whatever.
If you like stringstream, you can similarly do so.
What exactly do you mean by consecutive strings ?
Since you've mentioned that you're using C++ strings, try using the .string::append method.
string str, str2;
str.append("A");
str.append(str2);
Lookup http://www.cplusplus.com/reference/string/string/append/ for more overloaded calls of the append function.
it's pseudo code. you'll understand what i mean :D
int counter = 0, retval;
do
{
char filename[MAX_PATH];
sprintf(filename, "IMG00%d", counter++);
if(retval = CreateFile(...))
//ok, return
}while(!retval);
You have to keep a counter that is increased everytime you get a new name. This counter has to be saved when your application is ends, and loaded when you application starts.
Could be something like this:
class NameGenerator
{
public:
NameGenerator()
: m_counter(0)
{
// Code to load the counter from a file
}
~NameGenerator()
{
// Code to save the counter to a file
}
std::string get_next_name()
{
// Combine your preferred prefix with your counter
// Increase the counter
// Return the string
}
private:
int m_counter;
}
NameGenerator my_name_generator;
Then use it like this:
std::string my_name = my_name_generator.get_next_name();
How do I convert a string into an array of integers? Can I use sstream, because atoi doesn't work?!
As you said in the comments, you got a binary string and you want to convert it into integers. Use bitset for that:
std::istringstream is(str);
std::bitset<32> bits; // assuming each num is 32 bits long
while(is >> bits) {
unsigned long number = bits.to_ulong();
// now, do whatever you want with that long.
v.push_back(number);
}
If you only have one binary number in that string str, you can get away with
unsigned long number = std::bitset<32>(str).to_ulong();
Converting that in C is also possible...
long value;
char const *c = str;
for(;;) {
char * endp;
value = strtol(c, &endp, 2);
if(endp == c)
break;
/* huh, no vector in C. You gotta print it out maybe */
printf("%d\n", value);
c = endp;
}
atoi can't parse binary numbers. But strtol can parse them if you tell it the right base.
How exactly would you like the conversion to work?
Do you simply want an array containing the ASCII value of each character in the array? (so "abc" becomes [97, 98, 99, 0])?
Or do you want to parse the string somehow? ("1, 2, 3" becomes an array [1, 2, 3])
In the first case, in C++, I'd do something like this:
struct convert {
int operator()(char c) {
return static_cast<int>(c);
}
};
std::string str = "hello world";
std::vector<int> result;
std::transform(str.begin(), str.end(), std::back_inserter(result), convert())
Of course you could use a raw array instead of the vector, but since the length of the string is probably going to be variable, and then arrays are just asking for trouble.
If this wasn't what you wanted, you might want to edit your question to be more specific.
From what I understand, for input string "110013" would be converted to array {1,1,0,0,1,3}. Here is how to do it in C++:
string a = "1110011000";
vector<int> v;
for(int i = 0 ; i < a.length() ; i++){
v.push_back(a[i] -'0');
}
// Check the result
for(int i = 0 ; i < v.size() ; i++){
cout << v[i] << endl;
}
Quick string splitter routine:
convert(string str, string delim, vector<int>& results)
{
int next;
char buf[20];
while( (next= str.find_first_of(delim)) != str.npos ) {
if (next> 0)
results.push_back(atoi(str.substr(0,next), buf, 10));
str = str.substr(next+1);
}
if(str.length() > 0)
results.push_back(atoi(str.substr(0,next), buf, 10));
}
You can use stringstream instead of atoi (which does work, on a single int at a time)
int i;
stringstream s (input_string)
s >> i;
If you combine my and jalf's code, you'll get something really good.
Use the istream_iterator in conjunction with a string stream.
By Array I am assuming you really mean a std::vector as you don't know the number of integers at compile time. But the code can easily be modified to use an array rather than a vector.
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <iterator>
#include <algorithm>
int main()
{
std::string data = "5 6 7 8 9";
std::vector<int> store;
std::stringstream dataStream(data);
std::copy(std::istream_iterator<int>(dataStream),
std::istream_iterator<int>(),
std::back_inserter(store)
);
// This line just copies the store to the std::cout
// To verify it worked.
std::copy(store.begin(),
store.end(),
std::ostream_iterator<int>(std::cout,",")
);
}
Language: C
Header:
#include <stdlib.h>
Function Prototype:
long int strtol(const char *nptr, char **endptr, int base);
Example Usage:
strtol(nptr, (char **) NULL, 10);