使用C在二进制表示中打印int

gav*_*gav 23 c binary integer

我正在寻找一个允许我打印int的二进制表示的函数.到目前为止我所拥有的是什么;

char *int2bin(int a)
{
 char *str,*tmp;
 int cnt = 31;
 str = (char *) malloc(33); /*32 + 1 , because its a 32 bit bin number*/
 tmp = str;
 while ( cnt > -1 ){
      str[cnt]= '0';
      cnt --;
 }
 cnt = 31;
 while (a > 0){
       if (a%2==1){
           str[cnt] = '1';
        }
      cnt--;
        a = a/2 ;
 }
 return tmp;

}
Run Code Online (Sandbox Code Playgroud)

但是当我打电话时

printf("a %s",int2bin(aMask)) // aMask = 0xFF000000
Run Code Online (Sandbox Code Playgroud)

我输出像;

0000000000000000000000000000000000xtpYy(还有一堆未知字符.

这是函数中的缺陷还是我打印字符数组的地址或什么?对不起,我只是看不出我出错的地方.

NB代码来自这里

编辑:这不是家庭作业FYI,我正在尝试用不熟悉的语言调试别人的图像处理程序.然而,如果它被标记为家庭作业,因为它是一个基本概念,然后公平竞争.

Ada*_*itz 31

这是另一个在传递分配的缓冲区时更加优化的选项.确保它的大小正确.

// buffer must have length >= sizeof(int) + 1
// Write to the buffer backwards so that the binary representation
// is in the correct order i.e.  the LSB is on the far right
// instead of the far left of the printed string
char *int2bin(int a, char *buffer, int buf_size) {
    buffer += (buf_size - 1);

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

        a >>= 1;
    }

    return buffer;
}

#define BUF_SIZE 33

int main() {
    char buffer[BUF_SIZE];
    buffer[BUF_SIZE - 1] = '\0';

    int2bin(0xFF000000, buffer, BUF_SIZE - 1);

    printf("a = %s", buffer);
}
Run Code Online (Sandbox Code Playgroud)

  • +'0'部分做什么? (2认同)

Chr*_*oph 8

一些建议:

  • null-terminate你的字符串
  • 不要使用魔术数字
  • 检查返回值 malloc()
  • 不要转换返回值 malloc()
  • 因为您对二进制表示感兴趣,所以使用二进制运算而不是算术运算
  • 没有必要循环两次

这是代码:

#include <stdlib.h>
#include <limits.h>

char * int2bin(int i)
{
    size_t bits = sizeof(int) * CHAR_BIT;

    char * str = malloc(bits + 1);
    if(!str) return NULL;
    str[bits] = 0;

    // type punning because signed shift is implementation-defined
    unsigned u = *(unsigned *)&i;
    for(; bits--; u >>= 1)
        str[bits] = u & 1 ? '1' : '0';

    return str;
}
Run Code Online (Sandbox Code Playgroud)


Joh*_*ica 7

您的字符串不是以空值终止的.确保'\0'在字符串的末尾添加一个字符; 或者,您可以使用calloc而不是分配它malloc,这将使返回给您的内存归零.

顺便说一句,这段代码还有其他问题:

  • 使用时,它会在您调用时分配内存,让调用者负责free()分配的字符串.如果你只是在printf通话中拨打它,你就会泄漏内存.
  • 它会对数字进行两次传递,这是不必要的.你可以在一个循环中完成所有事情.

这是您可以使用的替代实现.

#include <stdlib.h>
#include <limits.h>

char *int2bin(unsigned n, char *buf)
{
    #define BITS (sizeof(n) * CHAR_BIT)

    static char static_buf[BITS + 1];
    int i;

    if (buf == NULL)
        buf = static_buf;

    for (i = BITS - 1; i >= 0; --i) {
        buf[i] = (n & 1) ? '1' : '0';
        n >>= 1;
    }

    buf[BITS] = '\0';
    return buf;

    #undef BITS
}
Run Code Online (Sandbox Code Playgroud)

用法:

printf("%s\n", int2bin(0xFF00000000, NULL));
Run Code Online (Sandbox Code Playgroud)

第二个参数是指向要存储结果字符串的缓冲区的指针.如果没有缓冲区,则可以传递NULLint2bin写入static缓冲区并将其返回给您.与原始实现相比,这样做的好处是调用者不必担心free()返回的字符串.

缺点是只有一个静态缓冲区,因此后续调用将覆盖先前调用的结果.您无法保存多个调用的结果以供以后使用.此外,它不是线程安全的,这意味着如果你从不同的线程以这种方式调用函数,它们可能会破坏彼此的字符串.如果这是一种可能性,你需要传递自己的缓冲区而不是传递NULL,如下所示:

char str[33];
int2bin(0xDEADBEEF, str);
puts(str);
Run Code Online (Sandbox Code Playgroud)