webentwicklung-frage-antwort-db.com.de

Drucken Sie ein int in binärer Darstellung mit C

Ich suche nach einer Funktion, mit der ich die binäre Darstellung eines int drucken kann. Was ich bisher habe, ist;

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;

}

Aber wenn ich anrufe

printf("a %s",int2bin(aMask)) // aMask = 0xFF000000

Ich bekomme Output wie;

0000000000000000000000000000000000xtpYy (und eine Reihe unbekannter Zeichen.

Ist es ein Fehler in der Funktion oder drucke ich die Adresse des Zeichen-Arrays oder etwas? Entschuldigung, ich kann einfach nicht sehen, wo ich falsch liege.

Der Code stammt von hier

BEARBEITEN: Es sind keine Hausaufgaben Zu Ihrer Information. Ich versuche, die Bildbearbeitungsroutinen einer anderen Person in einer fremden Sprache zu debuggen. Wenn es jedoch als Hausaufgabe markiert wurde, weil es ein elementares Konzept ist, dann ist es fair.

23
gav

Hier ist eine weitere Option, die mehr optimiert wird, wenn Sie den zugewiesenen Puffer übergeben. Stellen Sie sicher, dass es die richtige Größe hat.

// 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);
}
30
Adam Markowitz

Einige Vorschläge:

  • null-terminate deine Zeichenfolge
  • verwenden Sie keine magischen Zahlen
  • Überprüfen Sie den Rückgabewert von malloc().
  • gib nicht den Rückgabewert von malloc()
  • verwenden Sie binäre Operationen anstelle von arithmetischen Operationen, da Sie an der binären Darstellung interessiert sind
  • es ist nicht nötig, zweimal zu schleifen

Hier ist der Code:

#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;
}
8
Christoph

Ihre Zeichenfolge ist nicht nullterminiert. Stellen Sie sicher, dass Sie am Ende der Zeichenfolge ein '\0'-Zeichen hinzufügen. Oder Sie können es mit calloc anstelle von malloc zuweisen, wodurch der an Sie zurückgegebene Speicher auf Null gesetzt wird.

Übrigens gibt es andere Probleme mit diesem Code:

  • Bei der Verwendung weist es Speicherplatz zu, wenn Sie es aufrufen. Der Anrufer bleibt für die free()ing-Funktion des zugewiesenen Strings verantwortlich. Sie verlieren Speicher, wenn Sie ihn einfach in einem Aufruf von printf aufrufen.
  • Es macht zwei Durchgänge über die Nummer, was unnötig ist. Sie können alles in einer Schleife machen.

Hier ist eine alternative Implementierung, die Sie verwenden könnten.

#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
}

Verwendungszweck:

printf("%s\n", int2bin(0xFF00000000, NULL));

Der zweite Parameter ist ein Zeiger auf einen Puffer, in dem die Ergebniszeichenfolge gespeichert werden soll. Wenn Sie keinen Puffer haben, können Sie NULL übergeben, und int2bin schreibt in einen static-Puffer und gibt diesen an Sie zurück. Der Vorteil gegenüber der ursprünglichen Implementierung besteht darin, dass sich der Aufrufer nicht um free()ing der zurückgegebenen Zeichenfolge kümmern muss.

Ein Nachteil ist, dass es nur einen statischen Puffer gibt, sodass nachfolgende Aufrufe die Ergebnisse der vorherigen Aufrufe überschreiben. Sie können die Ergebnisse aus mehreren Anrufen nicht zur späteren Verwendung speichern. Außerdem ist es nicht threadsicher, dh wenn Sie die Funktion von verschiedenen Threads auf diese Weise aufrufen, können sie die Zeichenfolgen des anderen blockieren. Wenn dies eine Möglichkeit ist, müssen Sie Ihren eigenen Puffer übergeben, anstatt NULL, wie folgt:

char str[33];
int2bin(0xDEADBEEF, str);
puts(str);
7
John Kugelman

dies ist, was ich gemacht habe, um einen Interger als einen Code für die Bank anzuzeigen, er wird nach 4 Bits getrennt: 

int getal = 32;             /** To determain the value of a bit 2^i , intergers are 32bits long**/
int binairy[getal];         /** A interger array to put the bits in **/
int i;                      /** Used in the for loop **/
for(i = 0; i < 32; i++)
{
    binairy[i] = (integer >> (getal - i) - 1) & 1;
}

int a , counter = 0;
for(a = 0;a<32;a++)
{
    if (counter == 4)
    {
        counter = 0;
        printf(" ");
    }
   printf("%i", binairy[a]);
   teller++;
}

es könnte ein bisschen groß sein, aber ich schreibe es immer so (ich hoffe), dass jeder verstehen kann, was los ist. hoffe das hat geholfen.

1
Kirito

Hier ist ein einfacher Algorithmus. 

void decimalToBinary (int num) {

        //Initialize mask
        unsigned int mask = 0x80000000;
        size_t bits = sizeof(num) * CHAR_BIT;

        for (int count = 0 ;count < bits; count++) {

            //print
            (mask & num ) ? cout <<"1" : cout <<"0";

            //shift one to the right
            mask = mask >> 1;
        }
    }
1
Luqman_Ahmad
#include<stdio.h>
//#include<conio.h>  // use this if you are running your code in visual c++,      linux don't 
                     // have this library. i have used it for getch() to hold the screen for input char.

void showbits(int);
int main()
{
    int no;
    printf("\nEnter number to convert in binary\n");
    scanf("%d",&no);
    showbits(no);
//  getch();        // used to hold screen... 
                    // keep code as it is if using gcc. if using windows uncomment #include & getch()
    return 0;   

}
void showbits(int n)
{
    int i,k,andmask;

    for(i=15;i>=0;i--)
    {
        andmask = 1 << i;
        k = n & andmask;

        k == 0 ? printf("0") : printf("1");
    }

}
1
amol
#include <stdio.h>

#define BITS_SIZE 8

void
int2Bin ( int a )
{
  int i = BITS_SIZE - 1;

   /*
    * Tests each bit and prints; starts with 
    * the MSB
    */
  for ( i; i >= 0; i-- )
  {
    ( a & 1 << i ) ?  printf ( "1" ) : printf ( "0" );
  }
  return;
}

int
main ()
{
  int d = 5;

  printf ( "Decinal: %d\n", d );
  printf ( "Binary: " );
  int2Bin ( d );
  printf ( "\n" );

  return 0;
}
0
aldo núñez

der einfachste Weg für mich (für eine 8-Bit-Darstellung):

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

char *intToBinary(int z, int bit_length){

    int div;
    int counter = 0;
    int counter_length = (int)pow(2, bit_length);

    char *bin_str = calloc(bit_length, sizeof(char));

    for (int i=counter_length; i > 1; i=i/2, counter++) {
        div = z % i;
        div = div / (i / 2);
        sprintf(&bin_str[counter], "%i", div);
    }

    return bin_str;
}

int main(int argc, const char * argv[]) {

    for (int i = 0; i < 256; i++) {
        printf("%s\n", intToBinary(i, 8)); //8bit but you could do 16 bit as well
    }

    return 0;
}
0
KoSv

Einige Sachen:

int f = 32;
int i = 1;
do{
  str[--f] = i^a?'1':'0';
}while(i<<1);
  • Es ist in hohem Maße von der Plattform abhängig, aber ... vielleicht bringt diese Idee Sie zum Einstieg.
  • Verwenden Sie memset (str, 0, 33), um das gesamte Zeichenarray auf 0 zu setzen.
  • Vergessen Sie nicht zu befreien () !!! das char * -Array nach Ihrem Funktionsaufruf!
0
merkuro

Hier ist meine Lösung. Es erstellt eine Maske, die mit allen Nullen und einer 1 im äußersten linken Bit beginnt, und verschiebt sie logisch für jedes Bit in der 32-Bit-Ganzzahl angenommen. Die Bits werden nacheinander gedruckt, indem der Wert der aktuell maskierten Ganzzahl in einen booleschen Wert umgewandelt wird.

void printBits(int val){
    for(unsigned int mask = 0x80000000; mask; mask >>= 1){
         printf("%d", !!(mask & val));
    }
}
0

Zwei Dinge:

  1. Wo setzt du den NUL-Charakter ein? Ich kann keinen Ort sehen, an dem '\0' eingestellt ist.
  2. Int ist vorzeichenbehaftet und 0xFF000000 würde als negativer Wert interpretiert. while (a > 0) wird also sofort falsch sein.

Nebenbei: Die Malloc-Funktion im Inneren ist hässlich. Wie wäre es, einen Puffer für int2bin bereitzustellen?

0
Markus Schnell
#include <stdio.h>
int main(void) {

    int a,i,k=1;
    int arr[32]; \\ taken an array of size 32

    for(i=0;i <32;i++) 
    {
        arr[i] = 0;   \\initialised array elements to zero
    }

    printf("enter a number\n");
    scanf("%d",&a);  \\get input from the user

    for(i = 0;i < 32 ;i++)
    {
        if(a&k)    \\bit wise and operation
        {
            arr[i]=1;
        }
        else
        {
            arr[i]=0;
        }
        k = k<<1; \\left shift by one place evry time
    }
    for(i = 31 ;i >= 0;i--)
    {
        printf("%d",arr[i]);   \\print the array in reverse
    }

    return 0;
}
0
Anil Kumar

Zwei einfache Versionen codiert hier (mit leichter Umformatierung wiedergegeben).

#include <stdio.h>

/* Print n as a binary number */
void printbitssimple(int n) 
{
    unsigned int i;
    i = 1<<(sizeof(n) * 8 - 1);

    while (i > 0) 
    {
        if (n & i)
            printf("1");
        else
            printf("0");
        i >>= 1;
    }
}

/* Print n as a binary number */
void printbits(int n) 
{
    unsigned int i, step;

    if (0 == n)  /* For simplicity's sake, I treat 0 as a special case*/
    {
        printf("0000");
        return;
    }

    i = 1<<(sizeof(n) * 8 - 1);

    step = -1; /* Only print the relevant digits */
    step >>= 4; /* In groups of 4 */
    while (step >= n) 
    {
        i >>= 4;
        step >>= 4;
    }

    /* At this point, i is the smallest power of two larger or equal to n */
    while (i > 0) 
    {
        if (n & i)
            printf("1");
        else
            printf("0");
        i >>= 1;
    }
}

int main(int argc, char *argv[]) 
{
    int i;
    for (i = 0; i < 32; ++i) 
    {
        printf("%d = ", i);
        //printbitssimple(i);
        printbits(i);
        printf("\n");
    }

    return 0;
}
0
nik

Hier ist eine andere Lösung, die kein Zeichen * benötigt.

#include <stdio.h>
#include <stdlib.h>

void    print_int(int i)
{
    int j = -1;
    while (++j < 32)
        putchar(i & (1 << j) ? '1' : '0');
    putchar('\n');
}

int main(void)
{
    int i = -1;
    while (i < 6)
        print_int(i++);
    return (0);
}

Oder hier für mehr Lesbarkeit:

#define GRN "\x1B[32;1m"
#define NRM "\x1B[0m"

void    print_int(int i)
{
    int j = -1;
    while (++j < 32)
    {
        if (i & (1 << j))
            printf(GRN "1");
        else
            printf(NRM "0");
    }
    putchar('\n');
}

Und hier ist die Ausgabe:

11111111111111111111111111111111
00000000000000000000000000000000
10000000000000000000000000000000
01000000000000000000000000000000
11000000000000000000000000000000
00100000000000000000000000000000
10100000000000000000000000000000
0
Sequoya

// Das habe ich getan, als unser Lehrer uns darum gebeten hat

int main (int argc, char *argv[]) {

    int number, i, size, mask; // our input,the counter,sizeofint,out mask

    size = sizeof(int);
    mask = 1<<(size*8-1);
    printf("Enter integer: ");
    scanf("%d", &number);
    printf("Integer is :\t%d 0x%X\n", number, number);
    printf("Bin format :\t");
    for(i=0 ; i<size*8 ;++i ) {
        if ((i % 4 == 0) && (i != 0))  {
            printf(" ");
        }

        printf("%u",number&mask ? 1 : 0);

        number = number<<1;
    }
    printf("\n");

    return (0);
} 
0

Nicht so elegant, aber erreicht Ihr Ziel und es ist sehr leicht zu verstehen:

#include<stdio.h>

int binario(int x, int bits)
{
    int matriz[bits];
    int resto=0,i=0;
    float rest =0.0 ;
    for(int i=0;i<8;i++)
    {
        resto = x/2;
        rest = x%2;
        x = resto;
        if (rest>0)
        {
            matriz[i]=1;
        }
        else matriz[i]=0;
    }
    for(int j=bits-1;j>=0;j--)
    {
        printf("%d",matriz[j]);
    }
    printf("\n");
}
int main()
{
    int num,bits;
    bits = 8;
    for (int i = 0; i < 256; i++)
    {
        num = binario(i,bits);
    }
    return 0;
}