[英]C, strange behavior while using printf
这里我得到了一个以二进制表示形式打印整数的代码
#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;
}
它很有效,直到我试图挤出一些代码行代替
int2bin(count, buffer, BUF_SIZE - 1);
printf("%d = %s \n",count, buffer);
同
printf("%d = %s \n",count, int2bin(count, buffer, BUF_SIZE - 1));
它总是用这些日志打破我的输出:
805306368 = 00000000000000000000000000000000
805306369 = 00000000000000000000000000000001
805306370 = 00000000000000000000000000000010
805306371 = 00000000000000000000000000000011
805306372 = 00000000000000000000000000000100
805306373 = 00000000000000000000000000000101
等等...
你能解释一下为什么吗?
乍一看,它看起来像int2bin()
的第一个-1
是不必要的(因为循环开始时有一个-1)
请参阅Scott Mermelstein的答案进行解释
首先,可以肯定的是,问题不在于printf
。 让我们假设printf工作正常。 然后结论是你传递了不同的输入。 使用它,让我们详细了解您正在做的事情。
在你的两行示例中,它可以工作,因为您传入缓冲区。 可能是在你的单行示例中,你传递的地址不是缓冲区吗?
那么,在int2bin中,你添加buf_size - 1
,然后通过32(从31到0)包含数字,然后应该返回buffer
,对吧?
错误。
你将BUF_SIZE - 1
传递给int2bin
,即32,然后你从中减去1,所以你要加31而不是32,因此,不返回缓冲区。
很容易观察到这一点:在开始时打印出缓冲区的地址,在函数末尾打印缓冲区的地址。
简单的修复:
buffer += BUF_SIZE - 1
。 buffer
的原始值并返回该值 i = buf_size
。 基本上,epatel的第一眼回答是正确的。 我的回答只是提供了更多细节。
在int2bin中 ,用“0”覆盖缓冲区之前的字节。 编译器在这个地方为printf放置了参数“ count ”。
只需在通话中删除“-1”即可
printf("%d = %s \n",count, int2bin(count, buffer, BUF_SIZE));
由805306368是二进制的
00110000 00000000 00000000 00000000
和
00110000 = 48 ='0'
您的代码中还有一个缺陷,循环计数取决于buf_size! 我会建议用这种方式重写它。
#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;
}
你必须把这个函数称为
int2bin(count, buffer, BUF_SIZE)
否则该函数将从buffer minus 1byte
(这是一个下溢,在内存中放置一些垃圾)写入bit-chars到buffer minus 1byte
buffer + 31 bytes
你的代码相当模糊,包括计数循环和“试图变聪明”,例如fishy *buffer = (a & 1) + '0';
。 位掩码与ASCII编号无关,因此不要在同一操作中混合它们。 尝试使代码简单而不是复杂。 这是你问题的真正根源。
以更易读的方式重写代码,您的错误将消失。
#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);
}
除了buffer_size
可能出错之外(其他答案已经详细解释了)。 最简单的解决方法是添加
#include <stdio.h>
char * int2bin(int a, char * buffer, int buf_size);
到你的代码顶部。 这确实让它为我编译和工作。 两者都有
int2bin(count, buffer, BUF_SIZE - 1);
printf("%d = %s \n",count, buffer);
和
printf("%d = %s \n", count, int2bin(count, buffer, BUF_SIZE));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.