Hexadecimal number to decimal conversion I am a semi-beginner in C++ and I have a project in C++ to convert a hexadecimal integer into decimal equivalent, but I extended it and now this program can also convert a fractional part.

Logic I have used:


First the whole program is inside a do-while loop so that the user can convert a number as many time as desired.
Another do-while loop checks if the inputted number is valid or invalid. If invalid, it again asks the user for input.
A for loop counts the number of characters before the decimal point (if any).
Another for loop  converts the characters before the decimal point into a decimal number.
Another for loop converts the characters after the decimal point into a decimal fraction and adds it to the original number.
It prints it and asks if the user wants to again run the loop.


I have knowledge on selection statements (if-else), loops (for, while, do-while), operators and other basic things in C++.

Note: This program is compiled with MinGW and CodeBlocks. My school teacher uses TurboC++.

Please provide advice on things which I can understand; don't get too advanced. I want to score full marks on my school project but also want to understand the code.

// This is a C++ project for Unit Test 2 (2015-16). This program can convert a hexadecimal number into decimal equivalent.

#include &lt;iostream&gt;
#include&lt;string.h&gt;
#include&lt;math.h&gt;

using namespace std;
int main()
{
char choice;
cout&lt;&lt;" *** HEXADECIMAL TO DECIMAL CONVERTER ***";
do{                  //The whole program is inside a do-while loop, so that user can convert a number as many times as they want.
char hexd[120];
                                                         //This string will store the hexadecimal number input by the user.
int validn_count=0,length,lcopy,p=1,num,i,countp=0;
double decimal=0;

do{                                 //This do-while loop checks if the inputed number is valid or not. If not valid it again asks to enter the number.
cout&lt;&lt;"\n Enter a hexadecimal number for conversion (0-F): ";
cin&gt;&gt;hexd;
length=strlen(hexd);
for(int i=0;i&lt;length;++i)
{
    if( (hexd[i]&gt;=48 and hexd[i]&lt;=57) or (hexd[i]&gt;=65 and hexd[i]&lt;=70) or      (hexd[i]&gt;=97 and hexd[i]&lt;=102) or hexd[i]==46)
      ++validn_count;
    else
       {
        validn_count=0;
        cout&lt;&lt;"\n ! WARNING! Invalid HEXADECIMAL NUMBER!!!!";
        break;
       }
}

}while(validn_count==0);




for(i=0;i&lt;length;i++)   //This for loop checks how many characters are there before the decimal point (.)
{
    if(hexd[i]==46)
     break;
   else
     ++countp;


}
lcopy=countp;          // Copying the value of countp for usage in the  conversion.

for(i=0;i&lt;countp;++i)  // This for loop converts all the character before    the decimal point (.) into decimal number and stores it in the variable 'decimal'.
 {
  if(hexd[i]&gt;=48 and hexd[i]&lt;=57)
    num=((int)hexd[i]-48);
  else if(hexd[i]&gt;=65 and hexd[i]&lt;=70)
   num=((int)hexd[i]-55);
  else if (hexd[i]&gt;=97 and hexd[i]&lt;=102)
    num=((int)hexd[i]-87);

 decimal=decimal+(num*pow(16,--lcopy));
 }


for(i=(countp+1);i&lt;length;i++) // This for loop converts all the character after the decimal point (.) into decimal number and further stores it in the variable 'decimal'.
    {

    if(hexd[i]&gt;=48 and hexd[i]&lt;=57)
    num=((int)hexd[i]-48);
   else if(hexd[i]&gt;=65 and hexd[i]&lt;=70)
   num=((int)hexd[i]-55);
   else if (hexd[i]&gt;=97 and hexd[i]&lt;=102)
   num=((int)hexd[i]-87);

   decimal=decimal+(num*pow(16,-p));
    ++p;                                    //p is used for the multiply with 16 with negative powers.
   }


   cout&lt;&lt;" \n The decimal equivalent of hexadecimal number "&lt;&lt;hexd&lt;&lt;" is "    &lt;&lt;decimal;
  cout&lt;&lt;"\n Do you want to convert another hexadecimal number into decimal?   (Y/N): ";  // Asks if the user again wants to do a conversion.
 cin&gt;&gt;choice;
 }while(choice=='Y' or choice=='y');
cout&lt;&lt;"\n\n **** THANK YOU FOR USING THIS SOFTWARE ****";
return 0;
}
To take a quick first stab at some style issues:


Follow a consistent indentation style. This makes the code extremely readable, and you will thank yourself later when you come back to your code.

For example:

void foo()
{
  do 
  {
    bar();
  } while(0);
}

int main()
{
  foo();
}

Try to break down your program into smaller code blocks that you can reason about them independently, and perhaps even test them independently.

For example, how about start with this template, and fill in the code:

// checks
bool isValid(const std::string &amp;hexInput)
{

}

int64_t convertHexToDecimal(const std::string&amp; hexString)
{

}

int main()
{
    std::string input;
    std::cin &gt;&gt; input;

    while(isValid(input))
    {
        // perform the conversion
        int64_t convertedDecimal = convertHexToDecimal(input);

        // output the conversion
        std::cout &lt;&lt; "..." &lt;&lt; convertedDecimal &lt;&lt;  std::endl;

        // get new input
        std::cin &gt;&gt; input;
    }
}

Use std::string liberally instead of a character array. I think this is a more c++11 style of going about it. This will allow you to utilize the wealth of STL. This is more recognizable, and reduces the changes of introducing bugs in your hand-rolled while/for loop. 

auto found = input.find('.');
if (found != std::string::npos)
{
    std::cout &lt;&lt; "Period found at: " &lt;&lt; found &lt;&lt; '\n';
}

Your way of checking if the input string is hexadecimal is very awkward and unreadable. Whenever you use constants, you should declare them as consts, so you can update them without having to change the code.

A hexadecimal string has characters from one of the following set of characters:

0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F and the ., also the . should appear exactly once, and should probably not be the last character of the string. Also, you can use the characters directly for the comparison instead of the ASCII values. 

bool isValidHex = true;

// for_each will iterate between the the provided iterators
// for each position, you can pass a lambda function that checks
// the characters
std::for_each(
    str.begin(), 
    str.end(), 
    [&amp;isValidHex](char c) 
          {
            // std::cout &lt;&lt; "Checking" &lt;&lt; c &lt;&lt; std::endl; 
            if ((c &gt;= 'a' &amp;&amp; c &lt;= 'f') || 
                (c &gt;= 'A' &amp;&amp; c &lt;= 'F') || 
                (c &gt;= '0' &amp;&amp; c  &lt;= '9'))
            {
                // this is a valid hex.
            }
            else
            {
                isValidHex = false;
            }              
          });


If lambdas are not your style, you can also use the new c++11 loop style, which is much more readable.

for (char c : input)
{
    // perform checks here
}



To Be Continued..