Unzipping of characters

Asked

Viewed 41 times

1

I’m having difficulty in the following exercise

Using the right shift operator, the AND operator over bits and a mask, write a function called unzippaCaracters that receives the integer unsigned and unpack in two characters from an unsigned integer, match the unsigned integer with the 65280 mask (00000000 00000000 11111111111 00000000) and move the result in bits to the right. Assign the resulting value to a variable char. Then combine the unsigned integer with the mask 255 (00000000 00000000 00000000 11111111111). Assign the result to another char variable. The program must print the unsigned integer in bits before it is unzipped and then print the characters in bits to confirm that they have been unzipped correctly. :

The first character I can unzip, but the second character does not get the correct value (it is the same value as the first character unzipped).

Below I put the functions I am using to try to solve the exercise

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

void compactaCaracteres(char a,char b);
void descompactaCaracteres(unsigned valor);
void mostrarBits(unsigned valor);

int main(void){
   char var1,var2;

   printf("Digite um caractere:");
   scanf("%c",&var1);

   setbuf(stdin,NULL);

   printf("Digite um caractere:");
   scanf("%c",&var2);

   compactaCaracteres(var1,var2);
   return 0;
 }


 void compactaCaracteres(char a,char b){
   unsigned compacta = a;
   compacta <<= 8;
   compacta |= b;
   descompactaCaracteres(compacta);
}


 void descompactaCaracteres(unsigned valor){
   mostrarBits(valor);

   valor &= 65280;
   valor >>= 8;

   char a = valor;
   mostrarBits(a);

   char b = valor & 255;
   mostrarBits(b);
}

// Função utilizada para imprimir os bits

void mostrarBits(unsigned valor){
  unsigned contador;
  unsigned mascara = 1 << 31;

  printf("%10u = ",valor);

  for(contador = 1 ; contador <= 32; contador++){
    putchar(valor & mascara ? '1' : '0');
    valor <<= 1;

    if(contador % 8 == 0){
        putchar(' ');
    }
  }

  putchar('\n');
}

1 answer

2


The problem is that at the beginning of decompression the value is lost in the first and binary that is made:

void descompactaCaracteres(unsigned valor){
    mostrarBits(valor);

    valor &= 65280; // aqui
    valor >>= 8;

In doing valor &= 65280 or even valor = valor & 65280; is only with the second 8 bit block and the most to the right is lost.

The correct way to do the decompression would only be to get the result of and without modifying the variable valor, thus:

void descompactaCaracteres(unsigned valor) {
    mostrarBits(valor);

    char a = (valor & 65280) >> 8; //só obter sem alterar o valor
    mostrarBits(a);

    char b = valor & 255;
    mostrarBits(b);
}

With this change to the entry a and b gives it the following output:

Digite um caractere:Digite um caractere:     
     24930 = 00000000 00000000 01100001 01100010 
        97 = 00000000 00000000 00000000 01100001 
        98 = 00000000 00000000 00000000 01100010 

However, I take this opportunity to mention that the idea of functions is modularization and reuse. In this sense the function compactaCaracteres should return the compressed value, to allow to be called anywhere and do what you want with the result:

unsigned compactaCaracteres(char a,char b) {
// ^---
    unsigned compacta = a;
    compacta <<= 8;
    compacta |= b;
    return compacta; //<---
}

And the function descompactaCaracteres should also somehow return the result. Since there are two values to return a simple solution would be to pass two pointers with the values to be returned:

void descompactaCaracteres(unsigned valor, char *a, char *b) {
//                                              ^---------^--descompactados
    *a = (valor & 65280) >> 8;  //alterar o valor de a
    *b = valor & 255; //alterar o valor de b
}

In the main now I’d call it that:

int main(void) {
    char var1,var2;

    printf("Digite um caractere:");
    scanf("%c",&var1);

    setbuf(stdin,NULL);

    printf("Digite um caractere:");
    scanf("%c",&var2);

    unsigned compactado = compactaCaracteres(var1, var2); //compactar
    char a, b;
    descompactaCaracteres(compactado, &a, &b); //descompactar
    mostrarBits(a);
    mostrarBits(b);

    return 0;
}

Bit masks are also very common to use with define to facilitate. So could also do two that would facilitate. Something like:

#define ULITMOBYTE 255
#define PENULTIMOBYTE 65280

And use in appropriate locations.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.