Gabriele Gabriele - 23 days ago 6
C Question

Not fully-working operation in C (converter)

conta = 16;
oper3 = 0;
oper = 10;
oper2 = 15;
for(i=0;i<16;i++)
{
esadecimale[i] = 0;
}
for(i=0;i<16;i++)
{
binario[i] = 0;
}
esadecimale[10] = 'A';
esadecimale[11] = 'B';
esadecimale[12] = 'C';
esadecimale[13] = 'D';
esadecimale[14] = 'E';
esadecimale[15] = 'F';

printf("Inserisci il numero esadecimale da convertire (4 inserimenti): ");
for(i=4;i>0;i--)
{
scanf("%s",&esadecimale[i]);
}

while(oper3 < 4)
{
if(esadecimale[oper3] < 10)
{
oper = esadecimale[oper3];
while(oper > 0)
{
conta--;
oper2 = oper % 2;
binario[conta] = oper2;
oper = oper / 2;
}
}
else
{
while(!(esadecimale[oper3]==esadecimale[oper]))
{
oper++;
}
while(oper > 0)
{
conta--;
oper2 = oper % 2;
binario[conta] = oper2;
oper = oper / 2;
}

}
oper = 10;
oper3++;
}
printf("Il numero esadecimale convertito in binario e': ");
for(i=0;i<16;i++)
{
printf("%i",binario[i]);
}


This code is supposed to convert a hexadecimal number into a binary one.
I tried to use a -for cycle- instead of "while(oper3 < 4)" but it didn't fix the problem.

The output I get is something like 0000 0000 0000 1111 if I input F F F F
And 0000 0000 0000 1011 if I input A B C D

I guess it only converts the second hexadecimal character and in the wrong position too.

If possible I'd like a solution that doesn't require knowledge beyond the one you see in this code as the exercise clearly states that nothing more than arrays can be used, thank you.

Answer

Your code is too complicated and in places makes no sense (e.g. you have lots of lines of code to initialize esadecimale to then just overwrite some of it using scanf(). You fail to make the distinction between ASCII numbers and integer numbers so your whileloop runs on too long:

oper = esadecimale[oper3]; // contains '1' = 49 = 110001 binary
while(oper > 0) // loops seven times instead of once!

And your >= 10 case shouldn't be that different from your < 10 case. Here's a rewrite that addresses these issues:

void esadecimale_a_binario() {

    char esadecimale[4];

    printf("Inserisci il numero esadecimale da convertire (4 inserimenti): ");

    for (int i = 3; i >= 0; i--)
    {
        scanf("%c", &esadecimale[i]);
    }

    int binario[16] = { 0 };
    int conta = 15;
    int oper3 = 0;

    while (oper3 < 4)
    {
        int oper;

        if (esadecimale[oper3] < 10)
        {
            oper = esadecimale[oper3] - '0';
        }
        else
        {
            oper = esadecimale[oper3] - 'A' + 10;
        }

        while (oper > 0)
        {
            int oper2 = oper % 2;
            binario[conta--] = oper2;
            oper /= 2;
        }

        oper3++;
    }

    printf("Il numero esadecimale convertito in binario e': ");

    for (int i = 0; i < 16; i++)
    {
        printf("%i", binario[i]);
    }

    printf("\n");
}

But if you're going to use scanf(), make it work for you via it's %x input option. Then it's a simple matter of doing some parity testing:

#define CONTA 16

void esadecimale_a_binario() {

    printf("Inserisci il numero esadecimale da convertire (4 inserimenti): ");

    unsigned esadecimale;

    (void) scanf("%4x", &esadecimale);

    printf("Il numero esadecimale convertito in binario e': ");

    int binario[CONTA] = { 0 };

    for (int i = 0; i < CONTA; i++)
    {
        int j = CONTA - i - 1;

        binario[j] = esadecimale % 2;

        esadecimale /= 2;
    }

    for (int i = 0; i < CONTA; i++)
        {
            printf("%i", binario[i]);
        }

    printf("\n");
}

Using scanf() this way also makes your hexadecimal numbers case insensitive. This subroutine can be made much simpler (no array, fewer loops, etc.) but I've limited it to features you've already used in your original code.

TEST

% ./a.out
Inserisci il numero esadecimale da convertire (4 inserimenti): ABCD
Il numero esadecimale convertito in binario e': 1010101111001101
%