Turn hexadecimal strings to decimal integer value

Write a function in C++ that receives a string containing a 32-bit hexadecimal integer. The function must return the string's integer value in decimal form

Do not call built-in library functions that accomplish these tasks automatically.



// THis program basically turns a 32 bit hexadecimal string into the decimal integer value
// Ex: 01F12E0A = 32583178 or 00000012 = 18

// Arturo Ramirez
#include <iostream>
#include <cstring>
#include <string>
using namespace std;

int getDecimalForm(string);

int main()
{
//string binary;
// Reads both 0 and B as int 48 while B should be
string hexadecimal="01F12EBA";
int decimalForm;
int re = hexadecimal[0] , te = hexadecimal[1];


/*cout << "Input an eight digit binary string of 1s and 0s to find the integer value in decimal form:\n";
cin >> binary;

// Input validation
while (binary.size() != 8 || ((binary[0] != '0' && binary[0] != '1')
|| (binary[1] != '0' && binary[1] != '1') || (binary[2] != '0' && binary[2] != '1')
|| (binary[3] != '0' && binary[3] != '1') || (binary[4] != '0' && binary[4] != '1')
|| (binary[5] != '0' && binary[5] != '1') || (binary[6] != '0' && binary[6] != '1')
|| (binary[7] != '0' && binary[7] != '1')))
{
cout << "Input a valid eight digit binary string of only ones and zeros\n";
cin >> binary;
}*/

cout << "The 32-bit binary integer value is " << hexadecimal << endl;
cout << re << " " << te << " " << hexadecimal[0] - 55 << endl;
decimalForm = getDecimalForm(hexadecimal);

cout << endl << decimalForm << " is the same integer value expressed in decimal form";
}

// a function in C++ that receives a string containing a 16 - bit binary integer
int getDecimalForm(string hStr)
{
int value,
num = 1,
total = 0,
exponent = 0;

// Made adding happen starting from the right side
for (int i = (hStr.size() - 1); i >= 0; i--)
{
if ('0' <= hStr[i] <= '9')
{
cout << hStr[i] << " cat\n";
if (exponent != 0)
{
for (int j = 0; j < exponent; j++)
{
num *= 16;
}
}
value = num * (hStr[i] - 48);
}

if ('A' <= hStr[i] <= 'F')
{
cout << hStr[i] << " dog\n";
if (exponent != 0)
{
for (int j = 0; j < exponent; j++)
{
num *= 16;
}
}
value = num * (hStr[i] - 55);
}

// Keep adding the value of the binary integer
total += value;

num = 1;
exponent++;
}

return total;
}
Last edited on
Basically, I'm having trouble because the value for a char like 0 is also B because their value as an int is both 49 (which I though would be different.
OP's code, formatted and put in the code blocks they deleted while making their post:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#include<iostream>
#include <cstring>
#include <string>
using namespace std;

int getDecimalForm(string);

int main() {
  // string binary;
  // Reads both 0 and B as int 48 while B should be
  string hexadecimal = "01F12EBA";
  int decimalForm;
  int re = hexadecimal[0], te = hexadecimal[1];

  /*cout << "Input an eight digit binary string of 1s and 0s to find the integer
  value in decimal form:\n"; cin >> binary;

  // Input validation
  while (binary.size() != 8 || ((binary[0] != '0' && binary[0] != '1')
  || (binary[1] != '0' && binary[1] != '1') || (binary[2] != '0' && binary[2] !=
  '1')
  || (binary[3] != '0' && binary[3] != '1') || (binary[4] != '0' && binary[4] !=
  '1')
  || (binary[5] != '0' && binary[5] != '1') || (binary[6] != '0' && binary[6] !=
  '1')
  || (binary[7] != '0' && binary[7] != '1')))
  {
  cout << "Input a valid eight digit binary string of only ones and zeros\n";
  cin >> binary;
  }*/

  cout << "The 32-bit binary integer value is " << hexadecimal << endl;
  cout << re << " " << te << " " << hexadecimal[0] - 55 << endl;
  decimalForm = getDecimalForm(hexadecimal);

  cout << endl
       << decimalForm << " is the same integer value expressed in decimal form";
}

// a function in C++ that receives a string containing a 16 - bit binary integer
int getDecimalForm(string hStr) {
  int value, num = 1, total = 0, exponent = 0;

  // Made adding happen starting from the right side
  for (int i = (hStr.size() - 1); i >= 0; i--) {
    if ('0' <= hStr[i] <= '9') {
      cout << hStr[i] << " cat\n";
      if (exponent != 0) {
        for (int j = 0; j < exponent; j++) {
          num *= 16;
        }
      }
      value = num * (hStr[i] - 48);
    }

    if ('A' <= hStr[i] <= 'F') {
      cout << hStr[i] << " dog\n";
      if (exponent != 0) {
        for (int j = 0; j < exponent; j++) {
          num *= 16;
        }
      }
      value = num * (hStr[i] - 55);
    }

    // Keep adding the value of the binary integer
    total += value;

    num = 1;
    exponent++;
  }

  return total;
}


You posted code, but haven't asked us a question about it. How would you like us to help you?

EDIT: OP replied while I was drafting the post. Oops.

You might find it helpful to write a function that converts characters into the hexadecimal numbers they represent. For instance, if it's between '0' and '9' inclusive, do the normal thing, but if it's between 'A' and 'F' after uppercasing, subtract 'A' and add 10. Something like that.

Alternatively, some sort of associative structure (like std::map) would also work.

-Albatross
Last edited on
// THis program basically turns a 32 bit hexadecimal string into the decimal integer value
// Ex: 01F12E0A = 32583178 or 00000012 = 18


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// Example program
#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>

int main()
{
    using namespace std;
    cout << "Input hex digits: ";
    string hexstr;
    cin >> hexstr;
    
    size_t dec;
    stringstream ss;

    ss << std::hex << hexstr;
    if (ss >> dec)
    {
        cout << dec << '\n';   
    }
    else
    {
        cout << "Could not convert hex to decimal\n";   
    }
}

Input: 01F12E0A
32583178
Input: 00012
18
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>
#include <string>
#include <cctype>
using namespace std;


unsigned hexToInt( const string &hex )
{
   const string legit = "0123456789abcdefABCDEF";
   if ( hex.size() == 0 || hex.size() > 8 || hex.find_first_not_of( legit ) != string::npos )
   {
      cout << "Invalid hex string\n";
      return 0;
   }

   unsigned result = 0;
   for ( char c : hex ) result = 16 * result + ( isdigit( c ) ? c - '0' : 10 + toupper( c ) - 'A' );
   return result;
}


int main()
{
   string hex;
   cout << "Enter a 32-bit hex string: ";   cin >> hex;
   cout << hexToInt( hex );
}


Enter a 32-bit hex string: ABCDEF
11259375


Enter a 32-bit hex string: a1b2c3xy
Invalid hex string
0


Enter a 32-bit hex string: 12345678
305419896
BTW, I think you may have misread your assignment?
The instruction is to return an integer "in decimal form".

Integers do not have hexadecimal, decimal, binary, etc form (called "radix"). [I]strings[/i] have radix.

The conversion is made so much simpler by having a native integer value as an intermediary, but the output should (???) be a string.

I would clarify with your professor whether he/she is looking for a hex-string->integer or hex-steing->dec-string conversion.
Hello Eto,

PLEASE ALWAYS USE CODE TAGS (the <> formatting button), to the right of this box, when posting code.

Along with the proper indenting it makes it easier to read your code and also easier to respond to your post.

http://www.cplusplus.com/articles/jEywvCM9/
http://www.cplusplus.com/articles/z13hAqkS/

Hint: You can edit your post, highlight your code and press the <> formatting button.
You can use the preview button at the bottom to see how it looks.

I found the second link to be the most help.


I have been working with your program for awhile and found it does work, but needs a couple of tweaks.

You have two if statements with the format of: if ('0' <= hStr[i] <= '9'). This may look good on paper, but does not translate into code that works. For this I have most often seen and used:
if ('0' >= hStr[i] || hStr[i] <= '9'). Notice the lhs of the (||) is (>=) for both. Since you are looking for something between (0) and (9) or (A) and (F). As an example anything < "A", i.e., between 33 and 64 dec. would be considered true. Then when you try to convert that into a decimal number it would be a problem.

In the function "getDecimalForm" I found that the two if statements worked better as an if/else if statement.

After you define your variables, in main, you might want to consider something like this:
1
2
3
4
5
6
7
8
cout << "\n Input 8 hex numbers (12A45F78): ";

while (cin >> hexadecimal && hexadecimal.size() != 8)
{
	std::cout << "\n    Invalid hex number!\n    Must be 8 characters." << std::endl;

	std::cout << "\n Input 8 hex numbers (12A45F78): ";
}

The "cout" statements can be changed to anything that you like.

What you have set up now is a great way of testing the program, but eventually you will need to input and verify the string. You may also want to verify that each element of the string is a digit or the letters "A" - "F". I have not worked on this yet, but what I have in mind may streach the "Do not call built-in library functions that accomplish these tasks automatically.", but since it is not part of converting the number it might work. I was thinking of using the header file "<cctype>" and the function "isdigit()". There is also "std::toupper()" to make sure that the letters are in upper case. Just a thought for now.


Hope that helps,

Andy
hex has a direct conversion to binary, so you can digit by digit do a lookup table (size = 15, per nibble) to craft a binary integer which can then be printed in any format you like. I believe this is about as small / simple as it gets assuming your inputs fit into integers without having to go get a big integer library or cook up something for that. But here again, the assignment is a little fuzzy on what you really want. This is sort of what lastchance did, except he computes it.
Topic archived. No new replies allowed.