C 代码在它假设 运行 scanf 行时停止

C code stops when it suppose to run scanf line

考虑到输入是正确的二进制数,我写了一个代码,它应该计算从用户那里得到的二进制数中有多少个有效位 (1)。

每次代码应该 运行 main() 中的 scanf() 它只是卡住 ,它不会停止 运行ning,就是感觉自己在无限思考,不报错

这是我写的代码,在这种情况下会打印“请输入二进制数:”,然后就会卡住

#include <stdio.h>


void count_bits(long int UserNum){
    int cnt=0;
    while(UserNum>0)
    {
        if (UserNum%10==1)
        {
            cnt++;  
        }   
    }
    printf("there are %d active bits\n",cnt);
}


int main(){
    long int UserNum=0;

    printf("Please enter a binaric number: ");
    scanf("%ld" , &UserNum);
    count_bits(UserNum);
    
    return 1;
}

如果我像这样先写 scanf() 它甚至不会打印:

scanf("%ld" , &UserNum);
printf("Please enter a binaric number: ");

我做错了什么?

编辑: 例子 输入:1101100

输出:有4个有效位

输入:0110100111

输出:有6个有效位

基本上数一数有多少个

正如多条评论中指出的那样,UserNum>0 始终为真,因此循环永远不会停止。

但无论如何,count_bits 函数完全错误。对位进行模 10 运算是没有意义的。

你想要这个:

void count_bits(long int UserNum) {
  int cnt = 0;

  while (UserNum > 0)
  {
    if (UserNum % 2)  // if UserNum is odd, then bit no. 0 is 1
      cnt++;

    UserNum = UserNum / 2;  // division by 2 shifts bits to the right
  }

  printf("there are %d active bits\n", cnt);
}

由于我们在位级别上工作,因此使用位移位和位掩码操作会更加惯用:

void count_bits(long int UserNum) {
  int cnt = 0;

  while (UserNum > 0)
  {
    if (UserNum & 1)    // mask all bits but bit no. 0
      cnt++;

    UserNum = UserNum >> 1;   // shift bits to the right
  }
  printf("there are %d active bits\n", cnt);
}

但仍有改进的余地。尤其是负数将无法正常工作(虽然我没有测试,自己发现)。

还有更复杂的位计数方法,如下所述:How to count the number of set bits in a 32-bit integer?

我假设您想将用户输入的十进制数解释为二进制数。您的代码不会检查您的输入是否遵循此约定。如果您输入的数字包含 0 或 1 以外的数字,则每个非 1 的数字都将被解释为 0。(UserNum%10==1)

由于这个假设,我不讨论您通常必须使用 UserNum % 2UserNum & 1 测试位的事实。 (如果您想知道如何输入或打印二进制数而不是十进制数,请单独提问。)

请注意,如果您输入的数字位数过多,您可能很容易 运行 出现溢出问题。


主要问题:你在函数 count_bits 中有一个无限循环,因为你没有更新 UserNum.

你可以这样改:

void count_bits(long int UserNum){
    int cnt=0;
    while(UserNum>0)
    {
        if (UserNum%10==1)
        {
            cnt++;  
        }
        UserNum /= 10;
    }
    printf("there are %d active bits\n",cnt);
}

通过此更改,代码可以按预期工作。

Please enter a binaric number: 0110100111
there are 6 active bits

过大的数字示例。 (我加了一行printf("You entered %ld\n", UserNum);。)

Please enter a binaric number: 10110111011110111110
You entered 9223372036854775807
there are 0 active bits

如果在 main 中交换 printfscanf(在 count_bits 中无限循环),消息“请输入二进制数:”是未打印,因为它不包含换行符,默认情况下输出为 line-buffered。显然 scanf 导致刷新输出。

如果您将其更改为打印尾随换行符,例如

printf("Please enter a binaric number:\n");

它应该在进入 count_bits 之前打印出来(无限循环)。