0
votes

So I'm trying to create a program where the user enters a 12-bit binary hamming code sequence like "100010010001" and it should print out its corresponding ASCII character, which in this case is 'A'.

I'm trying to get my program to ignore the 4 parity bits which are positioned in _ _ 0 _ 1 0 0 _ 0 0 0 1 and shift the other 8 bits over so they're together. In the else statement, I tried to convert the remaining 8 bits to a character. When I attempt to run the program however, the program crashes after I type my binary sequence and press enter. This is the part of the program that I'm struggling with and I was wondering if someone could help me or give me hints as to what I'm doing wrong?

char charToBin(char usersInput[]) {
    char c = " ";
    for (int i = 12; i >= 0; i--) {
        if((i == 0) || (i == 1) || (i == 3) || (i == 7)){
            usersInput[i] = usersInput[i + 1];
        }else{
            c = strtol(usersInput[i], (char **)NULL, 2);
        }
    }
    return c;
}
4

4 Answers

0
votes

For your code, you can't use "strtol" without a twist. The char array that you give to "strtol" may not end with "\0". Also, does not matter what you do your array will always have 12 indexes unless you copy a "\0" to index 9 so that "strtol" know that it is the end of the input.

Also, sometimes loops are not the best. For your case, you already know how many indexes you are working with. There is no point in using a loop. Nonetheless, I wrote two methods and included the test code as an example below.

#include <stdio.h>

/*
 * This function generate a hammer binary digit string for testing.
 * It does not care about the validity of the hammer bit.
 * The array that is passed to this function should be the length of 12.
 */

void generateChar(int value, char * output){
    output[0] = '0';
    output[1] = '0';
    output[3] = '0';
    output[7] = '0';
    output[2] =  (value & 0b10000000) > 0? '1' : '0';
    output[4] =  (value & 0b01000000) > 0? '1' : '0';
    output[5] =  (value & 0b00100000) > 0? '1' : '0';
    output[6] =  (value & 0b00010000) > 0? '1' : '0';
    output[8] =  (value & 0b00001000) > 0? '1' : '0';
    output[9] =  (value & 0b00000100) > 0? '1' : '0';
    output[10] = (value & 0b00000010) > 0? '1' : '0';
    output[11] = (value & 0b00000001) > 0? '1' : '0';   
}

/* 
 * First method.
 *
 */
char charToBin(char usersInput[]) {
    char c = 0;
    c = usersInput[2] == '1'?  c | 0b10000000 : c;
    c = usersInput[4] == '1'?  c | 0b01000000 : c;
    c = usersInput[5] == '1'?  c | 0b00100000 : c;
    c = usersInput[6] == '1'?  c | 0b00010000 : c;
    c = usersInput[8] == '1'?  c | 0b00001000 : c;
    c = usersInput[9] == '1'?  c | 0b00000100 : c;
    c = usersInput[10] == '1'? c | 0b00000010 : c;
    c = usersInput[11] == '1'? c | 0b00000001 : c;

    return c;
}

/*
 * Second method.
 */
char charToBin2(char usersInput[]) {
    char temp[9];
    int pos = 0;
    temp[8] = '\0'; // Protect from overflow.

    for ( int i = 2; i < 12; i++ ){
        if ( i == 3 || i == 7 ) continue;
        temp[pos] = usersInput[i];
        pos++;
    }

    return (char) strtol(temp, (char **)NULL, 2);
}

int main(){
    char a[] = "100010010001";
    char t[12];
    int b;

    // Test for method 1
    for ( int i = 0; i < 256; i++ ){
        generateChar(i, t);
        b = charToBin(t);
        printf("%d ", (unsigned char) b );
    }

    printf("\n\n");

    // Test for method 2
    for ( int i = 0; i < 256; i++ ){
        generateChar(i, t);
        b = charToBin2(t);
        printf("%d ", (unsigned char) b );
    }

    return 0;
}
0
votes
if((i == 0) || (i == 1) || (i == 3) || (i == 7)){
            usersInput[i] = usersInput[i + 1];
        }else{

In here your if (condition), the curly bracket after that is not necessary.

if((i == 0) || (i == 1) || (i == 3) || (i == 7))
            usersInput[i] = usersInput[i + 1];
        else{

that would fix a bit maybe

0
votes

You program has two compile error:

  1. You can not assign string to character ( c= " ") ;
  2. The strtol call takes a string, not a character

After fixing the compile error, two fixes are needed to logic: 1. Perform the filtering of the input string from left to right, to avoid copying position 12 to 11, 11 to 10, which will result in duplicating the last positions. An extra counter is needed to help with the compaction. 2. Perform the strtol once, after the input is fully compacted.

char charToBin(char usersInput[]) {
    char j = 0 ;
    // Copy relevant input positions, INCLUDING terminating NUL byte at position 12.
    for (int i = 0; i <= 12 ; i++) {
        if((i == 0) || (i == 1) || (i == 3) || (i == 7)){
                continue ;
        } ;
        usersInput[j] = usersInput[i] ;
        j++ ;
    } ;
    char c = strtol(usersInput, (char **)NULL, 2);
    return c;
}

0
votes

Alternatively you could use bit operations. Something like:

char charToBin(char usersInput[]) {
    unsigned c = strtol(usersInput, NULL, 2);
    unsigned part1 = c & 0xFu;
    unsigned part2 = c >> 1u & 0x70u;
    unsigned part3 = c >> 2u & 0x80u;
    return (char) (part1 | part2 | part3);
}

Which would give with your input of

char userInput[] = "100010010001";
char ch = charToBin(userInput);
printf("result: %c(%d)\n", ch, ch);

the following output on the console:

result: A(65)