当前位置:  开发笔记 > 程序员 > 正文

你将如何在每日WTF中实现嘲讽功能?

如何解决《你将如何在每日WTF中实现嘲讽功能?》经验,为你挑选了1个好方法。

2008-11-28 每日WTF以下代码:

static char *nice_num(long n)
{
    int neg = 0, d = 3;
    char *buffer = prtbuf;
    int bufsize = 20;

    if (n < 0)
    {
        neg = 1;
        n = -n;
    }
    buffer += bufsize;
    *--buffer = '\0';

    do
    {
        *--buffer = '0' + (n % 10);
        n /= 10;
        if (--d == 0)
        {
            d = 3;
            *--buffer = ',';
        }
    }
    while (n);

    if (*buffer == ',') ++buffer;
    if (neg) *--buffer = '-';
    return buffer;
}

你会怎么写的?



1> Adam Rosenfi..:

如果你是一位经验丰富的C程序员,你会发现这段代码实际上并不那么糟糕.这是相对简单的(对于C),它的速度非常快.它有三个问题:

    它在LONG_MIN(-2,147,483,648)的边缘情况下失败,因为否定这个数字会产生二进制补码

    它假设32位整数 - 对于64位长,20字节的缓冲区不够大

    它不是线程安全的 - 它使用全局静态缓冲区,因此同时调用它的多个线程将导致竞争条件

问题#1很容易通过特殊情况解决.为了解决#2,我将代码分成两个函数,一个用于32位整数,另一个用于64位整数.#3有点困难 - 我们必须更改界面以使其完全是线程安全的.

这是我的解决方案,基于此代码,但经过修改以解决这些问题:

static int nice_num(char *buffer, size_t len, int32_t n)
{
  int neg = 0, d = 3;
  char buf[16];
  size_t bufsize = sizeof(buf);
  char *pbuf = buf + bufsize;

  if(n < 0)
  {
    if(n == INT32_MIN)
    {
      strncpy(buffer, "-2,147,483,648", len);
      return len <= 14;
    }

    neg = 1;
    n = -n;
  }

  *--pbuf = '\0';

  do
  {
    *--pbuf = '0' + (n % 10);
    n /= 10;
    if(--d == 0)
    {
      d = 3;
      *--pbuf = ',';
    }
  }
  while(n > 0);

  if(*pbuf == ',') ++pbuf;
  if(neg) *--pbuf = '-';

  strncpy(buffer, pbuf, len);
  return len <= strlen(pbuf);
}

说明:它在堆栈上创建一个本地缓冲区,然后以与初始代码相同的方法填充该缓冲区.然后,它将其复制到传递给函数的参数中,确保不会溢出缓冲区.它还有一个INT32_MIN的特例.如果原始缓冲区足够大,则返回值为0;如果缓冲区太小且返回结果字符串,则返回值为1.

推荐阅读
夏晶阳--艺术
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有