简体   繁体   English

C,使用printf时的奇怪行为

[英]C, strange behavior while using printf

Here i got a code which prints integer in binary representation 这里我得到了一个以二进制表示形式打印整数的代码

#define BUF_SIZE 33
int main() {
    for (int count = 0; count <=25; count++){

        char buffer[BUF_SIZE];
        buffer[BUF_SIZE - 1] = '\0';

        int2bin(count, buffer, BUF_SIZE - 1);
        printf("%d = %s \n",count, buffer);
    }
}

char *int2bin(int a, char *buffer, int buf_size) {
    buffer += (buf_size - 1);

    for (int i = 31; i >= 0; i--) {
        buffer--;
        *buffer = (a & 1) + '0';
        a >>= 1;
    }

    return buffer;
}

it works great until I'm trying to squeeze some lines of code replacing 它很有效,直到我试图挤出一些代码行代替

int2bin(count, buffer, BUF_SIZE - 1);
printf("%d = %s \n",count, buffer);

with

printf("%d = %s \n",count, int2bin(count, buffer, BUF_SIZE - 1));

It totaly breaks my output with these logs: 它总是用这些日志打破我的输出:

805306368 = 00000000000000000000000000000000
805306369 = 00000000000000000000000000000001
805306370 = 00000000000000000000000000000010
805306371 = 00000000000000000000000000000011
805306372 = 00000000000000000000000000000100
805306373 = 00000000000000000000000000000101

and so on... 等等...

could you please explain why is that? 你能解释一下为什么吗?

At first glance it looks like the first -1 in int2bin() is not necessary (as the loop start of with one -1) 乍一看,它看起来像int2bin()的第一个-1是不必要的(因为循环开始时有一个-1)

See Scott Mermelstein answer for explanation 请参阅Scott Mermelstein的答案进行解释

First of all, it's a safe bet that the issue isn't with the printf . 首先,可以肯定的是,问题不在于printf Let's assume printf works right. 让我们假设printf工作正常。 The conclusion then is that you're passing different input to it. 然后结论是你传递了不同的输入。 Working with that, lets look in detail at what you're doing. 使用它,让我们详细了解您正在做的事情。

In your two-line example, it works because you pass in buffer. 在你的两行示例中,它可以工作,因为您传入缓冲区。 Could it be that in your one-line example, you're passing an address that isn't buffer? 可能是在你的单行示例中,你传递的地址不是缓冲区吗?

Well, in int2bin, you add buf_size - 1 , and then work your way through 32 (From 31 to 0 inclusive) numbers, and should consequently be returning buffer , right? 那么,在int2bin中,你添加buf_size - 1 ,然后通过32(从31到0)包含数字,然后应该返回buffer ,对吧?

Wrong. 错误。

You're passing in BUF_SIZE - 1 to int2bin , which is 32. Then you're subtracting 1 from that, so you're adding 31 instead of 32, and consequently, not returning buffer. 你将BUF_SIZE - 1传递给int2bin ,即32,然后你从中减去1,所以你要加31而不是32,因此,不返回缓冲区。

Easy way to observe this: print out the address of buffer at the start, and the address of buffer at the end of the function. 很容易观察到这一点:在开始时打印出缓冲区的地址,在函数末尾打印缓冲区的地址。

Easy fixes: 简单的修复:

  • You could set your first line of int2bin to say buffer += BUF_SIZE - 1 . 您可以将int2bin的第一行设置为buffer += BUF_SIZE - 1
  • You could simply save buffer s original value and return that 您可以简单地保存buffer的原始值并返回该值
  • You could not use a seemingly arbitrary hardcode in your for loop, instead setting i = buf_size . 您不能在for循环中使用看似任意的硬编码,而是设置i = buf_size

Basically, epatel's first glance answer is right. 基本上,epatel的第一眼回答是正确的。 My answer just provides more detail. 我的回答只是提供了更多细节。

in int2bin you overwrite the byte before the buffer with an '0'. int2bin中 ,用“0”覆盖缓冲区之前的字节。 The compiler have laid the parameter " count " for printf at this place. 编译器在这个地方为printf放置了参数“ count ”。

Just remove "-1" in your call 只需在通话中删除“-1”即可

printf("%d = %s \n",count, int2bin(count, buffer, BUF_SIZE));

By the was 805306368 is binary 由805306368是二进制的

00110000 00000000 00000000 00000000 00110000 00000000 00000000 00000000

and

00110000 = 48 = '0' 00110000 = 48 ='0'

There is an other defect in your code, loop count depends on buf_size! 您的代码中还有一个缺陷,循环计数取决于buf_size! I would recomment to rewrite it this way. 我会建议用这种方式重写它。

#define BUF_SIZE sizeof(int)
int main() {
  for (int count = 0; count <=25; count++){

    char buffer[BUF_SIZE + 1];
    buffer[BUF_SIZE] = '\0';

    int2bin(count, buffer, BUF_SIZE);
    printf("%d = %s \n",count, buffer);
  }
}

char *int2bin(int a, char *pBuffer, int buf_size) {
   char *buffer = pBuffer + buf_size;

   for (int i = buf_size; i > 0; i--) { // loop count depends on buf_size!!!
     buffer--;
     *buffer = (a & 1) + '0';
     a >>= 1;
   }

   return pBuffer;
}

You have to call the function as 你必须把这个函数称为

int2bin(count, buffer, BUF_SIZE)

otherwise the function will write bit-chars from buffer minus 1byte (that's an underflow that put some garbage around in the memory) to buffer + 31 bytes 否则该函数将从buffer minus 1byte (这是一个下溢,在内存中放置一些垃圾)写入bit-chars到buffer minus 1byte buffer + 31 bytes

Your code is rather obscure with down counting loops and "trying to be smarts", such as the fishy *buffer = (a & 1) + '0'; 你的代码相当模糊,包括计数循环和“试图变聪明”,例如fishy *buffer = (a & 1) + '0'; . Bit masking has nothing to do with ASCII numbers so don't mix them in the same operation. 位掩码与ASCII编号无关,因此不要在同一操作中混合它们。 Try to make the code simple instead of complicated. 尝试使代码简单而不是复杂。 That is the true source of your problem. 这是你问题的真正根源。

Rewrite the code in a more readable manner and your bugs will go away. 以更易读的方式重写代码,您的错误将消失。

#include <stdio.h>
#include <stdint.h>

void int_to_bin (char bin[32+1], uint32_t val)
{
  for(int i=0; i<32; i++)
  {
    uint32_t mask = 1 << (32 - 1 - i); // -1 to compensate for zero indexing

    if( (val & mask) != 0)
    {
      bin[i] = '1';
    }
    else
    {
      bin[i] = '0';
    }
  }

  bin[32] = '\0';
}



int main()
{
  char buf[32+1]; 

  int_to_bin(buf, 0xAAAA);
  puts(buf);
  int_to_bin(buf, 0xCAFEBABE);
  puts(buf);
  int_to_bin(buf, 0x12345678);
  puts(buf);
}

Besides whatever might be wrong with buffer_size (the other answers already explain that in good detail). 除了buffer_size可能出错之外(其他答案已经详细解释了)。 The easiest fix is to add 最简单的解决方法是添加

#include <stdio.h>

char * int2bin(int a, char * buffer, int buf_size);

to the top of your code. 到你的代码顶部。 That did make it compile & work for me. 这确实让它为我编译和工作。 Both with 两者都有

int2bin(count, buffer, BUF_SIZE - 1);
printf("%d = %s \n",count, buffer);

and

printf("%d = %s \n", count, int2bin(count, buffer, BUF_SIZE));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM