【问题标题】:Extracting Digits from an Integer in C?从C中的整数中提取数字?
【发布时间】:2014-10-13 21:45:27
【问题描述】:
void print(int num, int digits)
{
    double mod, divi;
    int mod1, divi1;
    mod = pow(10, digits);
    divi = pow(10, digits-1);
    mod1 = (int)mod;
    divi1 = (int)divi;

    if(digits > 0)
    {
        printf("%d\n", ((num%mod1)/divi1));
        digits--;
        print(num, digits);
    }
    else
    {
        return;
    }
}

此函数旨在垂直打印来自num 的数字,但是当我运行它时,它打印的唯一内容是 0。我知道它得到了正确的位数,因为它打印的零数与数字中的位数相同,所以我在这里使用模数或除法一定有问题,我似乎找不到它。任何帮助将不胜感激!

获取数字的函数(可能问题出在这里?):

void getNum()
{   
    int num, digits=0;
    printf("Enter a number to be printed vertically: ");
    scanf("%d", &num);

    if(num < 0)
    {
        digits = 1;
    }
    while(num)
    {
        num = num/10; //Here was the problem. Num was 0 once i passed it to print()
        digits++; //Simply added a new variable to fix it. Thanks all!
    }

    print(num, digits);
}

【问题讨论】:

  • 为我工作。你的意见是什么?
  • pow() 可能会返回一个低于预期整数值的值。最好在截断为 int 之前对结果进行舍入 round(pow(10,digits));。一定要先#include &lt;math.h&gt;
  • 我只输入任意长度的随机数,总是得到全 0,与位数相同。
  • 也许我刚刚添加的函数是错误所在。 (获取数字)
  • 好吧,看着它我意识到我是多么愚蠢。在将 num 传递给函数之前,我将其设置为等于 0。抱歉!

标签: c integer-division


【解决方案1】:

我认为您的代码没有任何问题,只是它过于复杂并且不必要地使用了浮点数学。

这里有一个替代方案:

void print(int num, int digits)
{
    if (digits > 0) {
        print(num / 10, digits - 1);
        printf("%d\n", num % 10);
    }
}

诀窍是在递归调用之后移动打印。这允许更简单的逻辑。

【讨论】:

  • num &lt; 0 时有一个有趣的输出。但 OP 也是如此。
  • 我将它复制粘贴到我的代码中,但奇怪的是仍然全为 0...我已经编辑了上面的内容以添加我的 getNum 函数,也许问题出在那儿?
  • @abzib:是的,问题就在那里。您修改 num 直到它变为零,然后在其新的零值上调用 print。
  • @chux-ReinstateMonica,可能并不重要,但在开始时添加此条件可解决该问题。 if (num&lt;0){ num *=-1; }
【解决方案2】:

这是解决我的问题的方法。在将num 传递给函数之前,我将其设置为0。我只是声明了另一个变量 num1 以在 while 循环中使用,而不是传递给函数的实际 num

代码

void getNum()
{   

    int num, num1, digits=0;
    //get the num
    printf("Enter a number to be printed vertically: ");
    scanf("%d", &num);
    num1 = num;

    //Loop to find how many digits are in the number
    while(num1)
    {
        num1 = num1/10;
        digits++;
    }
    //call function to print
    print(num, digits);
}

【讨论】:

    【解决方案3】:
    int print(int num, int digits)
    {
        int min = 0;
        if (digits > 0) {
            min = print(num / 10, digits - 1);
            if(num %10)
               printf("%s%d\n", num < 0 && !(min++) ? "-" : "", abs(num % 10));
        }
        return min;
    }
    
    int print1(int num, int digits)
    {
        int min = 0;
        if (digits > 0) {
            min = print1(num / 10, digits - 1);
            if(num %10)
            {
                printf("%s", num < 0 && !(min++) ? "-\n" : "");
                printf("%u\n", abs(num % 10));
            }
        }
        return min;
    }
    
    int main()
    {
        print(-1234, 9);
        printf("\n-------------\n\n");
        print1(-23456565, 9);
    }
    

    【讨论】:

      【解决方案4】:

      通过对NPE answer 稍加改动,我得到了消除digits 参数并适用于负数的代码版本。


      代码

      void print(int num)
      {
          if (num < 0){
              num *=-1; 
          }
      
          if (num > 0) {
              print(num / 10);
              printf("%d\n", num % 10);
          }
      }
      

      [编辑1和2]正确INT_MIN溢出

      感谢 chux 的建设性 cmets 我更正了潜在的 INT_MIN 否定溢出。 Another similar topic by chux .

      void print(int num)
      {
      
          #if INT_MIN < -INT_MAX
          ///In two's complements systems.
          ///handle special case
      
          if ( num == INT_MIN ) {
            //fprintf(stderr, "Houston, we have a problem\n");
      
            // Maybe return or exit here.
            //~ 2147483647 -> 2147483648
            print(INT_MAX/10);
            print(INT_MIN%10); //portable version ///print(8);
            return;
          }
      
          if (num < 0){   
                  //num =-((unsigned)num);
                  num *=-1; 
          }
      
          #endif  
      
          if (num > 0) {
              print(num / 10);      
              printf("%d\n",  num%10);
          }
      
      }
      

      现在如果我们打电话给print()

      int number = INT_MIN;// a negative number
      
      print(-120);
      printf("\n");
      print(-321);
      
      print(number);
      

      输出

      1
      2
      0
      
      3
      2
      1
      Houston, we have a problem
      

      [编辑3]

      更改代码也适用于print(0)

      int zeroSignal=1;
      
      void print(int num)
      {
      
          #if INT_MIN < -INT_MAX
          ///In two's complements systems.
          ///handle special case
      
          if ( num == INT_MIN ) {
            ///fprintf(stderr, "Houston, we have a problem\n");
            // Maybe return or exit here.
            //~ 2147483647 -> 2147483648
            print(INT_MAX/10);
            print(INT_MIN%10); //portable version ///print(8);
            return;
          }
      
          if (num < 0){   
                  //num =-((unsigned)num);
                  num *=-1; 
          }
      
          #endif  
      
      
          if (num==0 && zeroSignal){
              printf("Only zero: %d\n", 0);
          }
      
          if (num > 0) {
              zeroSignal = 0;
              print(num / 10);
              printf("%d\n",  num%10);
          }
      
          zeroSignal = 1;      
      }
      

      在上面的代码中,我使用全局整数 zeroSignal 来实现一种适用于 print(0) 的方式。

      【讨论】:

      • @chux-ReinstateMonica,好的。我想现在它处理- INT_MIN
      • print(8); 假定为INT_MIN == -2147483648。不需要这种假设,也不需要可移植编程。考虑print(INT_MIN%10); 并删除fprintf(stderr, ...
      猜你喜欢
      • 1970-01-01
      • 2019-02-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-03
      • 2020-07-20
      相关资源
      最近更新 更多