I need to create a program that creates a hamming code for a series of 7 bit ASCII char from the command line, flips a bit as determined from the corresponding number on the command line, and then corrects the code.
I'm up to the creating hamming code part.
All of my functions except for createHamming() work as intended for the time being, so don't worry about anything except that function. I just included all the code so that people can run it.
I did have it generating the Hamming code correctly, but when I put code that was previously in the createHamming() function into their own functions (the four methods that check parity using the four check bits) to increase readability/modularity every thing went haywire. The hamming code is now being made to be like 20+ bits long when it should be 11 bits. The loops that set the bits don't go higher than 10 so I don't know how thats even in the realm of possibilities. Does anyone have any idea whats wrong?
Code:
/*==========================================================
*
* Program Purpose: To read a short ASCII string from the command
* line along with a series of integers. It creates a Hammming code
* for each character and then flips the bit at a position determined by
* the corresponding number from the command line. It then
* corrects the code.
*
*============================================================
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
typedef unsigned long set;
int countArgs(int argc, char **argv);
void printBits(set a);
set decStrToSet(char dec[]);
set flipBit(set a, int bit);
set createHamming(set a);
set checkAndCorrectBits(set a);
int checkBit1(set b);
int checkBit2(set b);
int checkBit3(set b);
int checkBit4(set b);
int main(int argc, char *argv[]){
if(argc < 2){
//command line must have at least three arguments (one
//char, one integer)
printf("Error: invalid number of arguments\n");
exit(1);
}
char chars[256];
int nums[256];
strcpy(chars, argv[1]);//initializes chars with first word
strcat(chars, " ");//contatenates space between words
int i = 2;//loop starts with second word
int numWords = 1; //the number of words from command line
//copies all words from command line
while(isalpha(argv[i][0])){
strcat(chars, argv[i]);//concatenates current argument to chars array
strcat(chars, " ");//contatenates space between words
numWords++;
i++;
}
//copies numbers to int array
int j = 0; //index where current number is added
for(i = numWords + 1; i < argc; ++i){
nums[j] = decStrToSet(argv[i]);
j++;
}
for(i = 0; i <= numWords; i++){//loops through chars
printf("The bit pattern for %c is: ", chars[i]);
printBits((set)(chars[i]));
set a = createHamming((set)(chars[i]));
printf("The Hamming code for %c is: ", chars[i]);
printBits(a);
a = flipBit(a, nums[i]);
printf("Flipped bit %d. The recieved code is: ", nums[i]);
printBits(a);
printf("The check bits are ");
a = checkAndCorrectBits(a);
printf("The corrected code is: ");
printBits(a);
printf("\n\n");
}
return 0;
}
set checkAndCorrectBits(set a){
//checks the bits, prints the results of the check bits and the bit in error
//corrects the erroneous bit and returns the corrected set
set b;
return b;
}
set flipBit(set a, int bit){
//flips the bit at the position indicated by int bit
}
set createHamming(set a){
//creates hamming code (odd parity) for set
set b;
int set[4];//determines what check bits should be set
printf("Hamming code with 0's at check bits:\n");//DEBUG
//creates binary code of appropriate length with 0's at check bits
int i = 0;
int k = 6; //index of set a
for(i = 10; i >= 0; i--){
//sets check bits to zero
if(i == 0 || i == 1 || i == 3 || i == 7){
b &= ~(1 << i); //clears the i-th bit of set b
printf("Setting check bit to zero: ");//DEBUG
printf("0\n");//DEBUG
}
//sets data bits
else{
if(a & (1 << k)){
b |= 1 << i; //sets the i-th bit of set b
printf("Setting data bit to one: ");//DEBUG
printf("1\n");//DEBUG
}
else{
b &= ~(1 << i); //clears the i-th bit of set b
printf("Setting data bit to zero: ");//DEBUG
printf("0\n");//DEBUG
}
k--;
}
}
//determines what check bits yield odd parity
//first check bit
set[0] = checkBit1(b);
//second check bit
set[1] = checkBit2(b);
//third check bit
set[2] = checkBit3(b);
//fourth check bit
set[3] = checkBit4(b);
//creates hamming code
i = 0;
int j = 3; //index of set[]
for(i = 10; i >= 0; i--){
//sets check bits
if(i == 0 || i == 1 || i == 3 || i == 7){//if i is check bit
if(set[j] == 0){//if the check bit does NOT return odd parity
b |= 1 << i; //sets the i-th bit of set b
printf("Setting check bit %d\n", (i + 1));//DEBUG
}
j--;
}
}
return b;
}
set decStrToSet(char dec[]){
//converts dec string to set
char *ptr;
set a = strtol(dec, &ptr, 10);
return a;
}
void printBits(set a){
//prints the bits of a set
//does not print leading zeroes
int print = 0; //boolean, set to 1 when ready to print
int i = 0;
int check4 = 2; //checks if 4 digits have been printed, if so loop prints space
for(i = 31; i >= 0; i--){
if(a & (1 << i)){ //checks if i-th bit is set (starting at 0))
print = 1;
printf("1");
}
else if(print == 1){//prints 0's only if it is NOT a leading zero
printf("0");
}
if(print == 1){
if(check4 == 4){
printf(" ");
check4 = 0;
}
check4++;
}
}
printf("\n");
}
int checkBit1(set b){
//returns 1 if the first check bit returns odd parity, 0 else
int num = 0;
int sum = 0;
int i = 0;
for(i = 0; i < 11; i++){
if((i + 1) % 2 != 0){//for odd positions
if(b & (1 << i)){
sum++;
}
}
}
if(sum % 2 == 0){
num = 0;
}
else{
num = 1;
}
printf("Sum: %d, is odd: %d\n", sum, num);
return num;
}
int checkBit2(set b){
//returns 1 if the second check bit returns odd parity, 0 else
int num = 0;
int sum = 0;
int check = 1; //counts how many bits have been checked. If < 0, then bit is not checked
int i = 0;
for(i = 1; i < 11; i++){
if(check > 0){
if(b & (1 << i)){
sum++;
}
}
if(check == 2){//if two have been checked, then goes back to skip mode
check = -2;
}
check++;
}
if(sum % 2 == 0){
num = 0;
}
else{
num = 1;
}
printf("Sum: %d, is odd: %d\n", sum, num);//DEBUG
return num;
}
int checkBit3(set b){
int sum = 0;
int check = 1;
int i = 0;
int num = 0;
for(i = 3; i < 11; i++){
if(check > 0){
if(b & (1 << i)){
sum++;
}
}
if(check == 4){//if four have been checked, then goes back to skip mode
check = -4;
}
check++;
}
if(sum % 2 == 0){
num = 0;
}
else{
num = 1;
}
printf("Sum: %d, is odd: %d\n", sum, num);//DEBUG
return num;
}
int checkBit4(set b){
int sum = 0;
int check = 1;
int i = 0;
int num = 0;
for(i = 7; i < 11; i++){
if(check > 0){
if(b & (1 << i)){
sum++;
}
}
if(check == 8){//if eight have been checked, then goes back to skip mode
check = -8;
}
check++;
}
if(sum % 2 == 0){
num = 0;
}
else{
num = 1;
}
printf("Sum: %d, is odd: %d\n", sum, num);//DEBUG
return num;
}
Sample input:
lab3 Hi 0 9
Sample output:
The bit pattern for H is: 100 1000
Hamming code with 0's at check bits:
Setting data bit to one: 1
Setting data bit to zero: 0
Setting data bit to zero: 0
Setting check bit to zero: 0
Setting data bit to one: 1
Setting data bit to zero: 0
Setting data bit to zero: 0
Setting check bit to zero: 0
Setting data bit to zero: 0
Setting check bit to zero: 0
Setting check bit to zero: 0
Sum: 2, is odd: 0
Sum: 2, is odd: 0
Sum: 1, is odd: 1
Sum: 1, is odd: 1
Setting check bit 2
Setting check bit 1
The Hamming code for H is: 100 0000 0010 0100 0110 0010 0001 1
Flipped bit 0. The recieved code is: 100 0000 0010 0100 0110 0010 0001 1
The check bits are The corrected code is: 1
The bit pattern for i is: 110 1001
Hamming code with 0's at check bits:
Setting data bit to one: 1
Setting data bit to one: 1
Setting data bit to zero: 0
Setting check bit to zero: 0
Setting data bit to one: 1
Setting data bit to zero: 0
Setting data bit to zero: 0
Setting check bit to zero: 0
Setting data bit to one: 1
Setting check bit to zero: 0
Setting check bit to zero: 0
Sum: 3, is odd: 1
Sum: 4, is odd: 0
Sum: 1, is odd: 1
Sum: 2, is odd: 0
Setting check bit 8
Setting check bit 2
The Hamming code for i is: 100 0000 0010 0100 0111 0110 0011 0
Flipped bit 9. The recieved code is: 100 0000 0010 0100 0111 0110 0011 0
The check bits are The corrected code is: 1