0

因此,我编写了一个使用递归将十进制数转换为十六进制数的函数,但我似乎无法弄清楚如何将前缀“0x”和前导零添加到转换后的十六进制数中。假设我将数字 18 传递给我的函数的参数。等效的十六进制数应为 0x00000012。但是,我最终只能得到 12 作为我的十六进制数。当我传入一个十六进制数 0xFEEDDAD 时也是如此。我最终只得到没有前缀的 FEEDDAD 作为我的答案。有人可以帮我解决这个问题吗?我在下面列出了我的代码。另外,我只能使用 fputc 来显示我的输出。

const char digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";

void hexout (unsigned long number, FILE * stream) 
{
     long quotient;
     long remainder;

     quotient = number / 16;
     remainder = number % 16;


     if(quotient != 0)
       hexout(quotient,stream);


     fputc(digits[remainder],stream);
}
4

3 回答 3

1
void hexout (unsigned long number, FILE * stream) 
{
    fprintf(stream, "0x%08lX", number);
}

如果你不能使用 fprintf(既不是 sprintf),你可以使用这种代码(没有递归,但堆栈上的 8 字符数组):

const char digits[] = "0123456789ABCDEF";

void hexout(unsigned long number, FILE * stream)
{
  unsigned long int input = number;
  unsigned long int quotient;
  unsigned long int remainder;
  unsigned short ndigit = 0;
  char result[8] = {0};

  // Compute digits
  do
  {
     quotient  = input / 16;
     remainder = input % 16;
     result[7-ndigit] = digits[remainder];
     input = quotient;
     ndigit++;
  }
  while (ndigit < 8);

  // Display result

  fputc('0', stream);
  fputc('x', stream);
  for (ndigit = 0; ndigit < 8; ndigit++)
  {
    fputc(result[ndigit], stream);
  }
}

当然,这可以改进很多......

于 2013-10-08T07:35:14.647 回答
0

将数字添加到字符串,并使用 . 打印出带有零填充的字符串fprintf。或者只是fprintf用来开始。

于 2013-10-08T07:34:15.530 回答
0

你自己的hexout失败原因很明显。当值达到 0 时,您不能“继续”输出多个零,因为您不知道已经发出了多少数字。另外,你不知道什么时候加上“0x”——它应该在你开始发出十六进制数字之前,但你怎么知道你在开始呢?

这样做的合乎逻辑的方法是不使用递归,而是使用简单的循环。再说一遍——没有说,但可以肯定的是,这是一个家庭作业,在这种情况下,任何数量的愚蠢限制都是可能的(“在不使用字符'{'的情况下编写 C 程序”浮现在脑海中)。在您的情况下,它是“您必须使用递归”。

必须在递归函数中添加一个计数器;当它达到 0 时,你知道你有 output 0x,如果它不是 0 ,你需要输出一个十六进制数字,不管你的值是否为 0 。有几种方法可以向递归函数添加计数器:全局变量(这将是最简单和最丑陋的方式,所以请不要停止阅读这里),static变量——仅在语义上比全局变量更好—— - 或传递引用参数(有人说这是一个神话,但最终结果还是一样)。

哪种方法最适合您,取决于您如何为使用该方法的原因辩护。

¹所以是printf("0x%08X")“不合逻辑”的解决方案吗?是的。它解决了问题,但没有任何进一步的见解。这个赋值的目的不是找出它的存在printf及其参数,而是学习如何(以及为什么)使用递归。

于 2013-10-08T09:23:00.770 回答