In C, I want to take a string (from the user), scan it by bit, and print out the number of unset bit. The string length will not be greater than 127. I also want to exclude the null character that is at the end of the string. For the string "hi", my output is 25 even though it should be 9. Not sure what I am doing incorrectly.
int unset(char* s){
size_t len = strlen(s);
char *bin = malloc(len*8);
char x;
bin[0] = '\0';
for(int i=0; i<=len; ++i) { //convert the string to binary
if (s[i] != '\0'){
x = s[i];
for(int j=7; j>=0; --j){
if((x & (1 << j)) == 0) {
strcat(bin,"0");
}
else {
strcat(bin,"1");
}
}
}
else {
break;
}
}
int n = strtol(bin, NULL, 2);
int count = 0;
for(int i=0; i<INT_SIZE; i++){ //count the unset bits
if((n & 1) == 0){
++count;
}
n >>= 1;
}
return count;
}
int main{
char sen[128];
printf("String: ");
scanf("%s", sen);
printf("%d", unset(sen));
return 0;
}
Your mistakes are:
00000000 00000000 01011000 01101001
. (only 2 characters is read, but it seems you are counting among full int
)int
.bin
has no room for terminating null-character, but strcat()
will add that. Therefore out-of-bound write will be performed.(void)
is missing after int main
.Instead of converting strings to binary string, you can count bits in characters directly:
#include <stdio.h>
int unset(const char* s){
int count = 0;
while(*s != '\0'){
for(int i=7; i>=0; --i){
if((*s & (1 << i)) == 0) count++;
}
s++;
}
return count;
}
int main(void){
char sen[128];
printf("String: ");
scanf("%127s", sen);
printf("%d", unset(sen));
return 0;
}