0

First of all I would like to say that this question is already related to this link (Convert ASCII string into Decimal and Hexadecimal Representations) but since I cannot add a comment, I need to ask something specific related to an answer on that thread.

The code from Jerry Coffin works for me:

for (int i=0; i<your_string.size(); i++)
    std::cout << std::hex << (unsigned int)your_string[i] << " ";

but what I would like to do is instead of printing this out via cout, I would like to store it in an unsigned int variable because I need to pass this value to another function.

My code looks like this:

unsigned int Ascii2Hex(std::string sString2Convert)
{
  unsigned int uiHexVal;
  for (int i=0; i<sString2Convert.size(); i++)
  {
    uiHexVal << std::hex << (unsigned int)sString2Convert[i];
  }
  return (uiHexVal);
}

This obviously does not work because of the "<<" operator.

How can I work my way around this?

6
  • 1
    Whats the problem with just using (unsigned int)sString2Convert[i]? Commented Jul 12, 2015 at 3:09
  • 2
    Anything wrong with strtoul with a base of 16? Commented Jul 12, 2015 at 3:10
  • Check this: Might help cplusplus.com/forum/beginner/89588 Commented Jul 12, 2015 at 3:13
  • 1
    It looks like you are trying to convert a string containing hex digits back into a number. If that's the case your function is just wrong. stackoverflow.com/questions/1070497/… Commented Jul 12, 2015 at 3:13
  • stackoverflow.com/questions/5100718/integer-to-hex-string-in-c In the top ans, the return value is stream.str() probably you can store it in a string object! Commented Jul 12, 2015 at 3:23

2 Answers 2

1

Utility functions exist for this, and I believe you could use stringstreams with a similar syntax to what you actually mocked up above. Even so, there's always the quick-and-dirty way:

template <typename T> // Use only unsigned types or risk overflow
T ASCII2hex (std::string str)
{
    T ret = 0;
    for (int i = 0; i < sizeof(T) && i < str.size(); ++i)
        ret += str[i] << (8 * i);
    return ret;
}

There's also this incredibly dangerous and technically undefined but nevertheless elegant and strangely compelling solution:

template <typename T> // yadda yadda unsigned
T ASCII2hex_UNSAFE_DONT_USE_THIS_FUNCTION (std::string str)
{
    return *(T*) str.data(); // Note: overrun if str.size() < sizeof(T)!!!!
}
Sign up to request clarification or add additional context in comments.

3 Comments

hi @acwaters thanks! this code suggestion compiled... but how do i Call it? I get compile error when I use it. sorry for my ignorance. i just don't understand.
Right! Sorry, I should have explained a bit more. The example I gave is a function template; that means that the function can be parameterized with extra information, like types, before it's called. Basically, you can do this: char[] str = "Test"; unsigned x = ASCII2hex<unsigned> (str); unsigned long y = ASCII2hex<unsigned long> (str); unsigned char z = ASCII2hex<unsigned char> (str); You don't have to write a new version for each type; since they all do the same thing, you just tell it which type it'll be using, and it gives you the right answer for that type size.
However, you could just as well write the above as an ordinary function, returning whatever type you wish. Just get rid of the template and replace the Ts with, e.g., unsigned int.
1

What Jerry Coffin's code is doing, despite the cast to unsigned int, is converting the char to a string. But usually, the operator<< of cout just thinks: "oh, char, that's a letter right..." so it prints it as the letter it represents. So to print it as a hex value instead, he casts it to an int first.

That being said, here is the problem: the code converts each character separately to an unsigned int and then prints it. But you want to put all the characters in one unsigned int. And depending on your char and int size there only fit 4 or 8 characters in an int. If it is less than this you could do:

unsigned int res=0;
res |= string[0] << 24;
res |= string[1] << 16;
res |= string[2] <<  8;
res |= string[3];

(note that here << means bitshift)

So long story short, you cannot convert the whole string unless it is really short. But when you think about it, a string is already a list of numbers (representing characters). And remember: numbers are always binary, until you print them as text.

3 Comments

hi David, I think this could work. The ASCII string I am trying to convert is limited to 8 digits (ASCII letters if you may).
Hi @David Van Rijn I am having trouble with this solution since the ASCII text is more than 8 characters. I added some filling white spaces at the end but I actually just need the first 8. this is just in case the letters are not 8 characters eg: QLMJ2W the last 2 characters are white spaces. but to make sure, in the stringstream where i manipulate this value i added an extra 8 white spaces.
Well, you could put those in a 64 bit integer, and it does certainly speed up calculations, but it does make more sense to use a char[8] for this, or a char[9] with trailing zero. If you put it in an integer please use uint64_t. But (i don't know your application) i would write a small wrapper class for char[9] withe an operator const char* () and an operator<() and the like. Then you could even define your own operator>>(istream&, my8String&) so you can easily pull them out of stdin or whatevever.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.