问题描述
在C语言中,我想从用户那里获取一个字符串,逐位扫描,然后打印出未设置的位数。字符串长度将不大于127。我还想排除字符串末尾的空字符。对于字符串“ hi”,即使应为9,我的输出也为25。不确定我做错了什么。
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;
}
解决方法
您的错误是:
- 您正在计算
00000000 00000000 01011000 01101001
的零。 (仅读取2个字符,但看来您是在完整的int
中进行计数) - 127个字节太长,无法放入
int
。 - 分配给
bin
的缓冲区没有空间来终止空字符,但是strcat()
会添加它。因此将执行越界写入。 -
(void)
在int main
之后丢失。 - 缺少必需的标题。
您无需直接将字符串转换为二进制字符串,而可以直接计算字符中的位数:
#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;
}