如何改进此十六进制到十进制转换的C ++程序?

时间:2015-10-10 15:19:09

标签: c++

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

#include <iostream>
#include<string.h>
#include<math.h>

using namespace std;
int main()
{
char choice;
cout<<" *** 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<<"\n Enter a hexadecimal number for conversion (0-F): ";
cin>>hexd;
length=strlen(hexd);
for(int i=0;i<length;++i)
{
    if( (hexd[i]>=48 and hexd[i]<=57) or (hexd[i]>=65 and hexd[i]<=70) or      (hexd[i]>=97 and hexd[i]<=102) or hexd[i]==46)
      ++validn_count;
    else
       {
        validn_count=0;
        cout<<"\n ! WARNING! Invalid HEXADECIMAL NUMBER!!!!";
        break;
       }
}

}while(validn_count==0);




for(i=0;i<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<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]>=48 and hexd[i]<=57)
    num=((int)hexd[i]-48);
  else if(hexd[i]>=65 and hexd[i]<=70)
   num=((int)hexd[i]-55);
  else if (hexd[i]>=97 and hexd[i]<=102)
    num=((int)hexd[i]-87);

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


for(i=(countp+1);i<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]>=48 and hexd[i]<=57)
    num=((int)hexd[i]-48);
   else if(hexd[i]>=65 and hexd[i]<=70)
   num=((int)hexd[i]-55);
   else if (hexd[i]>=97 and hexd[i]<=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<<" \n The decimal equivalent of hexadecimal number "<<hexd<<" is "    <<decimal;
  cout<<"\n Do you want to convert another hexadecimal number into decimal?   (Y/N): ";  // Asks if the user again wants to do a conversion.
 cin>>choice;
 }while(choice=='Y' or choice=='y');
cout<<"\n\n **** THANK YOU FOR USING THIS SOFTWARE ****";
return 0;
}

我用过的逻辑:

  1. 首先整个程序在do-while循环中,以便用户可以根据需要转换一个数字。
  2. 然后另一个do-while循环检查输入的数字是有效还是无效,如果无效则再次要求用户输入。
  3. 然后for循环计算小数点前的字符数(如果有的话)。
  4. 然后另一个for循环将小数点前的字符转换为十进制数。
  5. 然后,另一个for循环将小数点后的字符转换为小数,并将原始数字加上。
  6. 然后打印它并询问用户是否想再次运行循环。
  7. 我是C ++的半初学者,我在C ++中有一个项目将十六进制整数转换为十进制等值,但我扩展了它,现在这个程序也可以转换小数部分。

    您能否请专家就如何改进此代码提供一些建议?我希望它尽可能多地提供“错误证明”。

    我对选择语句(if-else),循环(for,while,do-while),运算符和C ++中的其他基本知识有所了解。

    注意:此程序使用MinGW和CodeBlocks编译。我的学校老师使用TurboC ++。

    P.S:我的英语很差,这不是我的第一语言,我把小数点写成小数点......对不起。

2 个答案:

答案 0 :(得分:0)

除了使用现有的库,例如std::istringstreamsscanf,另一种方法是查找表(数组)。

您还应该查找以下功能:isdigitisxdigittolowertoupper

static const char char_to_decimal[] = "0123456789";
static const char char_to_hex[] = "0123456789ABCDEF";

char * const p = strchr(char_to_decimal, digit_character);
if (p)
{
  value = p - char_to_decimal;
}

要打印十六进制数字:

char hex_digit_char = char_to_hex[digit];

答案 1 :(得分:0)

我会做这样的事情:

const char *HexadecimalToDecimal(const char *hexa)
{
    static char str[12];

    unsigned long len = strlen(hexa);

    // skip the initial '0x' if any
    if (len > 2 && hexa[0] == '0' && hexa[1] == 'x')
    {
        hexa += 2;
        len -= 2;
    }

    if (len >0 && len <= 8)
    {
        unsigned int value = 0;

        char c;
        while ((c = *hexa++ | 0x20))
        {
            value <<= 4;

            if (c >= '0' && c <= '9')
                value += c - '0';
            else if (c >= 'a' && c <= 'f')
                value += 10 + c - 'a';
            else
                break;
        }

        if (hexa[-1] == 0)
        {
            sprintf(str, "%u", value);
            return str;
        }
    }

    strcpy(str, "err");
    return str;
}

因此你可以这样做:

fprintf("0xab45F > %s", HexadecimalToDecimal("0xab45F");

甚至更好,如果你想测试你可以定义一个宏,如:

#define hexdec(s) printf(#s " = %s\n", HexadecimalToDecimal(#s))

然后你的主要看起来像这样:

int main(int argc, char *argv[])
{
    hexdec(1234);
    hexdec(0x200);
    hexdec(0x516c27f);
    hexdec(ff0000);
    hexdec(0xFFFFFFFF);
    hexdec(0124g); // err
    hexdec(012456789ab); // err
}

<强>解释

  • 十六进制字符串可以有前缀('0x')或不是
  • 它需要少于8个字符(例如,“0xFFFFFFFF”具有 8个字符,前缀为2)
  • 每个字符从0-F转换为0-15,值为 乘以16(将值向左移动4位)。那么 结果值将转换为带小数值的字符串。

如果发生错误(意外字符,字符串太长等),该函数将返回“err”