【问题标题】:Getting number of int digits获取整数位数
【发布时间】:2016-02-18 11:31:46
【问题描述】:

我正在使用fscanf(fp, "%d", &n) 函数从文件中读取整数。

有没有办法知道这个数字在没有循环的情况下有多少位?

【问题讨论】:

  • 没有理由不使用循环。所有目前的答案都不如简单的unsigned int digits = 1; while(n > base) { n /= base; digits++; }。使用字符串、浮点数和其他类似的废话只是糟糕的编程。你已经开始了一场关于谁能写出最糟糕的程序的竞赛,所以我认为这个问题对未来的读者有害。
  • unsigned int digits = 1; not_a_loop: if(n > base) { n /= base; digits++; goto not_a_loop; } 你去。比发布的任何答案都有效 100 倍。
  • @Lundin,当然你的意思是while(n >= base)。 (>= 与 >)。至于我,我会使用:unsigned int digits = 0; do { digits++; n /= base; } while(n); }.
  • 类似于stackoverflow.com/q/1068849/2410359(可能是骗子)
  • @Lundin - 你可能喜欢int n = 1; while (n /= 10) n++;

标签: c function digits


【解决方案1】:

你可以试试:

int count = 0;
fscanf(fp, "%d%n", &n, &count);

%n 说明符将count 放入到目前为止读取的字符数。

但是,此数字可以大于 n 的位数,因为 %d 说明符允许在读取数字之前跳过空白字符。

查看@pmg 的answer 了解如何计算这些空格。

【讨论】:

  • 看我的回答。我们有同样的想法,但我计算了空格并从结果中减去。
【解决方案2】:
int optionalwhitespace, characters;
if (fscanf(fp, " %n%d%n", &optionalwhitespace, &n, &characters) != 1) /* error */;
characters -= optionalwhitespace;
// characters now has the number of characters read to interpret the value in n

【讨论】:

    【解决方案3】:

    是的,通过将其读取为字符串:

    char buffer[256];
    fscanf(fp, "%s", buffer);
    int length = strlen(buffer);
    

    注意:如果它是负数,您可能需要打折 - 符号...

    假设你仍然想要整数值:

    int n = atoi(buffer);
    

    【讨论】:

    • strlen()不会给256吗?
    • @matt95 strlen 将在 \0 字符处停止计数。
    • 请注意,这比将其读取为 int 并使用循环要慢
    【解决方案4】:

    通过使用log 函数:

    int number_of_digits(unsigned int i)
    {
        return (int)(log(i+1) / log(10)) + 1;
    }
    
    int main (void)
    {
        int i = 52;
        printf("%d has %d digits\n", number_of_digits(i));
    }
    

    【讨论】:

      【解决方案5】:

      对于代码高尔夫方法,只需返回snprintf()的值

      width = snprintf(0, 0, "%u", (unsigned) n);
      

      【讨论】:

        【解决方案6】:

        你可以使用snprinf,这是比itoa更好的选择:

        int x = 0;
        scanf( "%d", &x );
        char buffer[20] = "";
        snprintf(buffer, sizeof(buffer), "%d", x);
        printf( "num of digits = %d", strlen(buffer) );
        

        【讨论】:

        • 为什么是 20?可以使用 1 或 printf( "num of digits = %d", snprintf(0, 0, "%d", x) );
        • @chux - 语法对我来说看起来很奇怪,但确实有效。 snprintf manpage 从来没有提到第一个参数可以是 NULL - 所以我想这个漏洞必须来自检查 snprintf 本身的代码??
        • 考虑使用 C 规范,而不是像 manapge 这样的派生引用。草稿版本很容易在网上搜索到。 “snprintf(char * restrict s, size_t n, const char * restrict format, ...); ...如果 n 为零,则不写入任何内容,并且 s 可能是空指针。... snprintf 函数返回如果 n 足够大时将写入的字符数...” 否需要利用或检查代码。
        【解决方案7】:

        您可以只计算该数字的 log10 并将其四舍五入,如下所示:

        int length = ceil(log10((double)n)) + 0.5;
        

        + 0.5 用于将浮点数转换为整数,因为像 3 这样的数字不能在浮点表示中显式写入 (int)3.0 可能会产生 2。我假设 ceil 不会由 @ 返回答案987654327@ 这永远不会发生。

        【讨论】:

        • 转换(double) 可能会在n 中丢失精度。
        • @chux 我以为是int 不是 64 位整数。
        • 添加 0.5 在这里没有用处。 ceil()返回一个整数值,为什么在转换为int时添加0.5只是为了截断@
        • @chux ceil 不返回整数值。 cplusplus.com/reference/cmath/ceil
        • C 规范说“ceil 函数计算不小于x 的最小整数值。”他们也错了吗?
        【解决方案8】:

        试试这个:

        #include <math.h>
        number > 0 ? (int) log10 ((double) number) + 1 : 1;
        

        【讨论】:

          【解决方案9】:

          有没有办法知道这个数字在没有循环的情况下有多少位?

          递归解决方案

          unsigned digit_count(unsigned x) {
            if (x >= 10) return digit_count(x /10) + 1;
            return 1;
          }
          

          【讨论】:

            【解决方案10】:
            #include<math.h>
            
            //rest of program
            fscanf(fp, "%d", &n)
            int length = (int)(log10(n)) +1;
            //rest of program
            

            【讨论】:

            • 错误...log10(*n)?我不认为您打算取消引用该整数作为指针。
            • 糟糕!已编辑。谢谢。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2015-04-18
            • 2015-05-30
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-07-20
            • 2015-05-06
            相关资源
            最近更新 更多