我不明白为什么下面的程序会将“z @”作为字符串返回。但是当我在此之前放置
printf("%s \n","");
时,它会返回“11110111”(如预期的那样)。
任何人都可以帮我理解这种行为吗?
非常感谢提前!
请查看我在下面发布的整个计划:
#include <stdio.h>
char * bin2str(unsigned char bin) {
char str[] = "00000000";
int i;
for (i=7; i>=0; i--) {
if ((bin%2)==0) {
str[i] = '0';
} else {
str[i] = '1';
}
bin = bin >> 1;
}
return ((char *) str);
}
int main() {
unsigned char testChar;
testChar |= 0b11110111;
printf("Let us test binary to string: \n\n \n");
//printf("%s \n","");
printf("%s \n", bin2str(testChar)); //now it returns rubbish, but when the previous line is uncommented it turns out to be working correctly. Why?
return 0;
}
答案 0 :(得分:4)
您正在从函数str
返回undefined behaviour的本地变量bin2str
。相反,您可以使用strdup()
(或等效使用malloc()
+ strcpy()
)复制它。
char *str = strdup("00000000");
并将其归还。
不要忘记free()
它!
答案 1 :(得分:1)
您正在bin2str()
内生成一个字符串作为局部变量。当bin2str()
正在执行时,该字符串将位于堆栈空间中。一旦函数返回,堆栈空间就不再有效,str指向的内存将包含程序是否在从bin2str()
的调用返回到{{1}的调用之间放入堆栈你打算打印printf()
。
备选方案:
将str
声明为静态。这样,str
将不会被放置在堆栈空间中,即使在函数结束后,其内容也将可用。谨防!因为这个解决方案不是线程安全的。
更改原型,使其接受第二个参数,该参数将是调用者必须提供的字符串的地址,str
将写入该数字的二进制表示。
答案 2 :(得分:0)
谢谢大家的反馈。哇,那太快了!
这是我的第一篇文章。
我做了改动。请在下面找到正确的功能程序(没有编译警告):
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char * bin2str(unsigned char bin) {
char *str = strdup("00000000");
int i;
for (i=7; i>=0; i--) {
if ((bin%2)==0) {
str[i] = '0';
} else {
str[i] = '1';
}
bin = bin >> 1;
}
return ((char *) str);
free(str);
}
int main() {
unsigned char testChar;
testChar |= 0b11110111;
printf("Let us test binary to string: \n\n \n");
printf("%s \n", bin2str(testChar));
return 0;
}