【问题标题】:Decimal to hexadecimal conversion code in C++C++中十进制到十六进制的转换代码
【发布时间】:2015-04-20 22:16:00
【问题描述】:

我是 C++ 编程的新手。我的任务是编码十进制到十六进制的转换。这是我到目前为止所做的。

#include <iostream>

int main()
{
    long dec;
    int rem;

    std::cout << "enter decimal number: ";
    std::cin >> dec;

    while (dec > 0) {
        rem = dec % 16;
        if (rem > 9) {
            switch (rem) {
               case 10: std::cout << "A"; break;
               case 11: std::cout << "B"; break;
               case 12: std::cout << "C"; break;
               case 13: std::cout << "D"; break;
               case 14: std::cout << "E"; break;
               case 15: std::cout << "F"; break;
            }
        }
        else {
            std::cout << rem;
        }
        dec = dec / 16;
    }
}

它向后给出答案,就像如果我输入一个十进制数字“650”它给出十六进制值A82,而答案应该是28A。谁能建议我应该做些什么来纠正它?

【问题讨论】:

  • iostream.h 自 1998 年 C++ 标准化以来一直不存在。那是很久以前的事了。
  • rem = dec % 16; 这就是问题所在。你总是在每次迭代中检查 low 数字。
  • 如果唯一的问题是它倒退了,那么您肯定可以想办法扭转你的情况;)
  • 如果你学会使用调试器并单步调试你的代码,你很快就会清楚问题是什么。
  • @πάνταῥεῖ 从问题的措辞来看,这听起来像是某种可能不是在寻找简单解决方案的任务。也许OP可以澄清。

标签: c++


【解决方案1】:

当然,它会向后给出答案。您的程序开始“从后面开始”分析给定的十进制数。具体来说,您正在转换以最不重要位开头的数字。处理完每个数字后,您立即将其输出。因此,您首先输出最不重要的数字,但十六进制和十进制系统都表示从最重要的数字开始的数字。换句话说,如果您的号码是十六进制的XYZ(表示十进制的16^2 * X + 16^1 * Y + 16^0 * Z),则将其输出为ZYX。尝试将所有数字保存在一个字符串中,在它的开头添加新数字:

string s = "";
while (dec > 0)   // Do this whilst the quotient is greater than 0.
{
  rem = dec % 16; // Get the remainder.
  if (rem > 9)
  {
    // Map the character given that the remainder is greater than 9.
    switch (rem)
    {
      case 10: s = "A" + s; break;
      case 11: s = "B" + s; break;
      case 12: s = "C" + s; break;
      case 13: s = "D" + s; break;
      case 14: s = "E" + s; break;
      case 15: s = "F" + s; break;
    }
  }
  else
  {
    s = char(rem + 48) + s; // Converts integer (0-9) to ASCII code.
    // x + 48 is the ASCII code for x digit (if 0 <= x <= 9)
  }
  dec = dec/16;
 }
 if (s == "") // if the number was 0, the string will remain empty
   cout << "0";
 else
   cout << s;

【讨论】:

  • 这可能是最好的答案,尽管重新格式化代码不会有什么坏处!
  • 当然不会。我只是关注这段代码的正确性,而不是它的美学或良好的编程时尚。
  • 为什么我们不能拥有both! :)
  • 如果while (dec &gt; 0) { ...} 更改为do { ...} while (dec &gt; 0);dec &lt;0,则不需要特殊测试if (s == "") cout &lt;&lt; "0";
【解决方案2】:

我现在正在使用 MFC Cpp,并使用 CString:

CString hex;
hex.Format("%x", 16766208); //ffd500 - use capital %X for FFD500

【讨论】:

    【解决方案3】:

    我的解决方案:

    /*  decimal /hexa
        Jose Anilto
    */
    #include <iostream>
    #include <cstring>
    
    
    using namespace std;
    
    
    string converte(int n, string x) {
    
        string hexa = {"0123456789ABCDEF"};
        return (n < 16 ? "0x" + (hexa[n] + x) : converte(n/16, hexa[n%16] + x));
    
    }
    
    int main () {
    
        int nd ;
        string y = "";
        cout << "\n Digite um numero: "; cin >> nd;
        cout << "\n Numero digitado: " << nd << "\n";
    
        cout << "\n Hexadecimal: " << converte(nd, y) << "\n";
    
     return 0;
    }
    

    【讨论】:

    • n &lt; 0 时失败。建议unsigned n.
    • 绿色。 Só vale para inteiros positivos。
    【解决方案4】:

    编码十进制到十六进制的转换。

    不诉诸递归,只需在最大可能大小的本地缓冲区中形成答案并向后填充即可。

    这个任务对于代码转储来说太有价值了。而是提出一个算法来指导。

      // Pseudo code
      long x
      L = MaxSizeNeeded(long) // hint:sizeof
      buffer[L]
      pointer p = last_element(buffer)
      *p = 0 // null character
      do {
        extract least base 16 digit of `x`
        *--p = text version of least digit
        x /= base
      } while (x)
      prepend "0x" if desired.
      Form string from `p` and return
    

    其他问题涉及x &lt; 0。将代码移动到unsigned long 或从输入-27 形成“-0x1B”,将值折叠到负数,如上所述转换,知道最小数字将是负数,最后根据需要应用符号。

    【讨论】:

      【解决方案5】:

      如果您想从十进制转换为二进制(基数 2)、十六进制(基数 16)等的解决方案!

      #include <iostream>
      using namespace std;
      
      void d2base(int n, int b);
      char arr[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
      
      int main()
      {
          int num, base;
      
          cout << "Enter decimal number to convert: ";
          cin >> num;
          cout << "Enter the base: ";
          cin >> base;
          cout << "\nNumber in " << base << " is ";
      
          d2base (num, base);
      }
      
      void d2base(int n, int b)
      {
          if (n > 0)
          {
              d2base(n/b, b);
              cout << arr[n%b];
          }
      }
      

      【讨论】:

      • 虽然此代码可能会回答问题,但提供有关它如何和/或为什么解决问题的额外上下文将提高​​答案的长期价值。
      【解决方案6】:

      最简单的解决方案:

      #include <iostream>
      using namespace std;
      int main(){
          int val;
          cin >> val;
          cout << hex << val << endl;
          return 0;
      }
      

      您的算法的修复 - 使用递归:

      #include <iostream>
      #include <conio.h>
      using namespace std;
      
      void print_hex(int value)
      {
          if (value == 0)
              return;
      
          int rem = value % 16;
          value /= 16;
          print_hex(value); //first execute recurency and print next value
      
          //after return print the less significant digit
          if (rem > 9)
              cout << (char)(rem - 10 + 'A');
          else
              cout << rem;
      }
      
      int main(int argc, char * argv[]) {
          cout << "enter decimal number: ";
          long dec;
          cin >> dec;
          print_hex(dec);
          cout << endl;
          return 0;
      }
      

      【讨论】:

      • 我认为您的意思是“递归”而不是“递归”。
      • 哦,不。不要让他为他的第一次尝试做一个递归算法。这只是卑鄙的。
      • main 返回int。总是。不是什么也不是void
      • 我复制了作者代码的第一个版本。但你说得对,应该是int main
      • 这个解决方案有个bug,如果输入0,则什么都不打印(如果value==0则返回)。最好将其更改为迭代而不是递归。
      【解决方案7】:

      如果唯一的错误是输出的顺序与您想要的相反,您可以将输出放入容器中。然后,将容器中的输出顺序颠倒再打印出来。

      将输出放入容器的一种方法是将输出发送到stringstream

      std::ostringstream sout;
      const char *hex = "0123456789ABCDEF";
      while (dec > 0) {
          rem = dec % 16;
          sout << hex[rem];
          dec = dec / 16;
      }
      std::string s(sout.str());
      std::reverse(s.begin(), s.end());
      std::cout << s;
      

      【讨论】:

      • dec == 0 时不打印任何内容。
      • @chux-ReinstateMonica 是的,我遵循了 OP 中 0 案例的行为规范。
      【解决方案8】:

      最简单的方法:把它变成一个字符串:

      string answer = "";
      while (dec > 0) {
          rem = dec % 16;
          if (rem > 9) {
              switch (rem) {
                 case 10: answer = "A" + answer; break;
                 case 11: answer = "B" + answer; break;
                 case 12: answer = "C" + answer; break;
                 case 13: answer = "D" + answer; break;
                 case 14: answer = "E" + answer; break;
                 case 15: answer = "F" + answer; break;
              }
          }
          else {
              answer = string(1, (char)rem-'0') + answer;
          }
          dec = dec / 16;
      }
      cout << answer;
      

      【讨论】:

        猜你喜欢
        • 2011-02-04
        • 1970-01-01
        • 2019-01-01
        • 1970-01-01
        • 2014-04-16
        • 2017-05-05
        • 2011-12-09
        • 1970-01-01
        相关资源
        最近更新 更多