-1

I am writing a small program convert hex representation of a string , it is a kata to improve my skills.

This is what I have come up with

std::vector<int> decimal( std::string const & s )
{

auto getint = [](char const k){
switch(k){
case 'f':
return 15;
case 'e':
return 14;
case 'd':
return 13;
case 'c':
return 12;
case 'b':
return 11;
case 'a':
return 10;
case '9':
return 9;
case '8':
return 8;
case '7':
return 7;
case '6':
return 6;
case '5':
return 5;
case '4':
return 4;
case '3':
return 3;
case '2':
return 2;
case '1':
return 1;
case '0':
return 0;
};

std::vector<int> result;

for( auto const & k : s )
{
result.push_back(getint(k));
}

return result;

}

I was wondering if there in another way to do this. I have considered to use something as an std::map as well, but I am uncertain which one might be faster. If there is another way to do this please add it.

Please keep in mind that I am doing this as a code-kata to improve my skills, and learn.

Thanks and TIA!

streetprog
  • 29
  • 3
  • 1
    You should worry about correctness before you worry about speed. You're converting `aa` to `{10, 10}` when it should be `{1, 7, 0}`. – molbdnilo Dec 22 '15 at 19:53
  • you have correctness issues , but would be nice to check this http://stackoverflow.com/questions/34365746/whats-the-fastest-way-to-convert-hex-to-integer-in-c/34366370#34366370 for fast way to write the getint() – g24l Dec 22 '15 at 23:47

3 Answers3

1

To start with, you can probably simplify your logic like so:

auto getint = [](char const k){
    if(k >= 'a' && k <= 'f') return (k - 'a');
    else if(k >= 'A' && k <= 'F') return (k - 'A');
    else if(k >= '0' && k <= '9') return (k - '0');
    else return -1;
}

Beyond that, there may exist a Standard Library function that does exactly this, which you might prefer depending on your specific needs.

Xirema
  • 19,889
  • 4
  • 32
  • 68
0

You can use strtol or strtoll to do most of the heavy lifting for you of converting from a base16 string to an integer value.

Then convert back to a regular string using a stringstream object.

// parse hex string with strtol
long value = ::strtol(s.c_str(), nullptr, 16);  //not shown - checking for errors. Read the manual page for more info

// convert value back to base-10 string
std::stringstream st;
st << value;
std::string result = st.str();

return result;
selbie
  • 100,020
  • 15
  • 103
  • 173
0

For the decimal digits it's very easy to convert a character to its digit, as the C++ specification says that all digits must be consecutive in all encodings, with '0' being the lowest and '9' the highest. That means you could convert a character to number by just subtracting '0', like e.g. k - '0'. There's no such requirement for the letters though, but the most common encoding (ASCII) the same is true, but it should not be counted on if you want to be portable.

You could also do it using e.g. std::transform and std::back_inserter, so no need for your own loop. Perhaps something like

std::transform(std::begin(s), std::end(s), std::back_inserter(result), getint);

In the getint function you could use e.g. std::isxdigit and std::isdigit to check if the character is a valid hexadecimal or decimal digit, respectively. You should probably be using e.g. std::tolower in case the hexadecimal digits are upper-case.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621