unix 如何将2位或2位以上的整数显示为字符串?

yrefmtwq  于 2022-11-04  发布在  Unix
关注(0)|答案(3)|浏览(153)

我的任务是创建一个函数来显示作为参数输入的数字。该函数必须能够显示int类型变量中所有可能的值。write()是唯一允许的函数。

void ft_putchar(char c)    
{
    write(1, &c, 1);
}

void ft_putnbr(int nb)
{
    if (nb < 0)
    {
        ft_putchar('-');

        ft_putchar(-nb + '0');
    }

    if ( nb > 0)
    {
        ft_putchar(nb + '0');
    }
}

我写了这个,但是很明显它不适用于两位或两位以上的整数,我怎么把它们显示为字符串呢?

kpbwa7wx

kpbwa7wx1#

write是唯一允许的函数。
更通用的解决方案是使用循环来处理10、100等。尝试除以10的最大幂,然后除以该幂的1/10,等等。
要处理所有的int有点棘手。要小心执行-INT_MIN的代码,因为这是 undefined behavior(UB)。相反,在打印符号后使用int的负边,因为负int比正int多。


# if INT_MAX == 2147483647

# define INT_POW_MAX (1000 * 1000 * 1000)

# elif INT_MAX == 32767

# define INT_POW_MAX (10 * 1000)

# else

// For greater portability, additional code needed

# error "TBD code"

# endif

void ft_putnbr(int nb) {
  if (nb < 0) {
    // Do not use -nb as that is UB when nb == INT_MIN
    ft_putchar('-');
  } else {
    nb = -nb;
  }
  // At this point, nb <= 0
  int pow10n = -INT_POW_MAX;

  // Skip leading 0 digits.
  while (pow10n < nb) {
    pow10n /= 10;
  }

  // Print the rest.
  do {
    int q = pow10n ? nb/pow10n : nb;
    ft_putchar(q + '0');
    nb -= q*pow10n;
    pow10n /= 10;
  } while (pow10n);
}

通过test harness

46scxncf

46scxncf2#

候选解决方案的测试工具:


# include <limits.h>

# include <stdio.h>

# include <stdlib.h>

# define ft_putchar putchar

void ft_putnbr(int nb) {
  // Your code here
}

void test(int i) {
  printf("%12d ", i);
  ft_putnbr(i);
  printf("\n");
}

int main() {
  int a[] = { INT_MIN, 0, 1, 2, 9, 10, 11,42, INT_MAX - 1, INT_MAX };
  size_t n = sizeof a / sizeof a[0];
  for (size_t i = 0; i < n ; i++) {
    if (a[i] > 0) test(-a[i]);
    test(a[i]);
  }
}

预期产出

-2147483648 -2147483648
           0 0
          -1 -1
           1 1
          -2 -2
           2 2
          -9 -9
           9 9
         -10 -10
          10 10
         -11 -11
          11 11
         -42 -42
          42 42
 -2147483646 -2147483646
  2147483646 2147483646
 -2147483647 -2147483647
  2147483647 2147483647
q7solyqu

q7solyqu3#

递归解决方案。
它还避免了-INT_MIN

void putint(int nb) {
  if (nb < 0) {
    ft_putchar('-');
    if (nb == INT_MIN) {
      putint(nb / -10);
      nb %= -10;
    }
    nb = -nb;
  }
  if (nb >= 10) {
    putint(nb/ 10);
    nb %= 10;
  }
  ft_putchar(nb + '0');
}

相关问题