【问题标题】:Displaying individual number with spacing on printf在 printf 上显示带有间距的单个数字
【发布时间】:2019-06-27 08:02:02
【问题描述】:

我正在编写一个代码来显示结果是显示单个数字和十进制等效值。 例如,如果 n 为 6,输入的数字为 110011,则打印输出为 1 1 0 0 1 1 十进制等值是 51

我已经获取并编辑了一个代码,但是它显示 “110011 110011 110011 110011 110011 110011”代替 “1 1 0 0 1 1”。

#include <math.h>

void main()
{
    int  num, binary, decimal = 0, base = 1, remainder, n, digits;

    printf("Please enter the number of digits:\n");
    scanf("%d", &n);

    printf("Please enter the %d digits:\n",n);
    scanf("%d", &num);
    binary = num;
    while (n > 0)
    {
        remainder = num % 10;
        decimal = decimal + remainder * base;
        num = num / 10 ;
        base = base * 2;
        printf("%d   ", binary);
        n--;
    }

    printf("\nIts decimal equivalent is = %d \n", decimal);
}



【问题讨论】:

标签: c binary decimal


【解决方案1】:

变量binary 中的值将成为下一行中变量num 中值的副本。

binary = num;

由于它之后永远不会更改,因此它将始终保持相同的值,即复制时 num 中的值的副本(参见上面的代码行)。
您的循环执行n 次(在您的示例中为六次)。
每次循环时,相同的复制值都会打印在以下代码行中。 因此,在您的示例中,原始值将被打印六次。

printf("%d   ", binary);

您实际上并没有提出问题(在 StackOverflow 上确实建议这样做)。
所以我回答了“为什么相同的值会打印六次?”的问题

您现在可能想问下一个问题,“如何获得所需的结果?”
这个问题很难回答,因为你的代码离实现这个目标还很远。

您必须以正确的顺序一一确定二进制数字。
您确实在代码中的以下行周围逐一确定数字。

remainder = num % 10;

但这是错误的顺序,它为您提供了从最不重要到最重要的数字。尝试输入“100011”以了解我的意思。

更准确地说,我不得不说我猜你想要从多到少的数字,但也许不是,在这种情况下更容易:打印remainder而不是binary

如果我是对的并且您确实希望最多或最少,那么您必须采取某种方式来反转数字。您可以先使用堆栈、数组、递归或其他(更复杂的)数学来确定位数。

【讨论】:

    【解决方案2】:

    您获得此输出的原因是因为每次调用 printf("%d ", binary); 都会将整个“二进制”变量打印到屏幕上,并且该变量包含数字而不是该数字的单个数字。

    访问数字的特定数字的最简单方法是首先将其除以 10 的某个幂,然后得到该数字的 mod10,例如:

    int number = 6543;
    int lastDigit = number % 10;
    int secondLastDigit = (number / 10) % 10;
    int thirdLastDigit = (number / 100) % 10;
    

    这是可行的,因为在 C 中除以整数会导致省略任何小数部分,因此如果除以 6543/10(如示例中所示),您将不会得到 654.3,而是 654。

    您可以创建一个函数,该函数将从任何位置返回一个数字,如下所示:

    int digitAt(int num, int pos)
    {
        // Divide num by 10^(pos - 1) to "shift" the number to the right
        num /= pow(10, pos - 1);
    
        // Return the last digit after the divisions
        return num % 10;
    }
    

    上述函数返回从右开始的数字(pos 1 = 最后一位,pos 2 = 倒数第二位)! 为了使这个功能更直观,您可以在除法之前水平翻转数字(123 变为 321)。

    我有点切题,回到原来的话题。要实现您想要的功能,您可以这样编写代码(只是 while 循环):

    while (n > 0)
    {
        remainder = num % 10;
        decimal = decimal + remainder * base;
        num = num / 10 ;
        base = base * 2;
        int binaryDigit = (binary / pow(10, n - 1)) % 10;
        printf("%d   ", binaryDigit);
        n--;
    }
    

    现在,您不必担心您的数字被反向读取的原因(就像在前面的函数示例中一样)是因为方便地,您的迭代器 n 已经在反向('从 n 到0' 而不是 'from 0 to n'),所以你在读最左边的数字之前是最右边的数字。

    希望有所帮助。

    [编辑] 正如回复中所指出的,在整数运算中使用 pow() 可能会导致不希望的结果。我的错。不过,有很多方法可以实现 10 的整数幂,比如

    int powerOf10(int exp)
    {
        int num = 1;
        while (exp > 0) {
            num *= 10;
            exp--;
        }
    
        return num;
    }
    

    应该做的工作。

    【讨论】:

    • 用双返回 pow 函数计算的 10 的幂是有风险的。它会产生不希望的结果。通常,不建议在纯整数计算中使用pow() 或其他浮点数学函数......许多 SO 问题处理其他问题。此外,OP 似乎已经意识到使用整数除法和模数。
    • @Yunnosch 感谢您指出这一点,我已经更新了答案。
    【解决方案3】:

    问题是你这样做了:

    printf("%d   ", binary);
    

    binary 始终是相同的值,即它永远不会改变,因此您会一次又一次地打印原始值。

    如果您将其更改为:

    printf("%d   ", remainder);
    

    事情会“好一点”,因为二进制模式将被打印但以相反的顺序。所以这不是解决方案。

    因此,您可以收集循环中的值并将它们存储在一个字符串中,以便在循环之后打印。喜欢:

    int main()
    {
        int  num, decimal = 0, base = 1, remainder, n;
    
        printf("Please enter the number of digits:\n");
        scanf("%d", &n);
    
        int idx = 2*n-1;
        char *str = malloc(2*n);  // Allocate memory for the string
        str[idx--] = 0;           // and zero-terminate it
    
        printf("Please enter the %d digits:\n",n);
        scanf("%d", &num);
    
        while (n > 0)
        {
            remainder = num % 10;
            decimal = decimal + remainder * base;
            num = num / 10 ;
            base = base * 2;
            str[idx--] = '0' + remainder;  // Put the "binary" (i.e. '0' or '1') char in the string
            if (idx>0) str[idx--] = ' ';   // Put a space in the string
            n--;
        }
    
        printf("%s", str);                 // Print the string
        printf("\nIts decimal equivalent is = %d \n", decimal);
    
        free(str);    // Free the string
    
        return 0;
    }
    

    【讨论】:

    • digitsbinary 在您的代码中都未使用-最好删除杂物(除非您故意让它们在上下文中显示您的编辑-然后至少应该将它们注释掉)
    • @DavidC.Rankin 我没有注意未使用的变量。答案已更新 - 感谢您告诉我。
    • 嗨,我想出了怎么做,但现在我无法解释这条线的用途:base = base * 2;
    • @78S base 用于表示各个位的价值贡献(如果设置)。即 - 如果设置了位 0,则将 1 加到 decimal - 如果设置了位 1,则将 2 加到 decimal - 如果设置了位 2,则将 4 加到 decimal - 如果设置了位 3,则加 8到decimal - ...等等。但是请注意,每次添加的值都会翻倍。这就是base = base * 2; 为您所做的 - 它计算“下一位的价值贡献”(如果已设置)。
    猜你喜欢
    • 2018-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多