题
我想将字符串与许多其他数据一起存储在二进制文件中,我使用下面的代码(当我真正使用它时,字符串将被 malloc'd)我可以写入该文件。我在十六进制编辑器中看过它。我不确定是否正确编写了空终止符(或者是否需要)。当我读回时,我得到的字符串长度与我存储的相同,但不是字符串。我究竟做错了什么?
FILE *fp = fopen("mybinfile.ttt", "wb");
char drumCString[6] = "Hello\0";
printf("%s\n", drumCString);
//the string length + 1 for the null terminator
unsigned short sizeOfString = strlen(drumCString) + 1;
fwrite(&sizeOfString, sizeof(unsigned short), 1, fp);
//write the string
fwrite(drumCString, sizeof(char), sizeOfString, fp);
fclose(fp);
fp = fopen("mybinfile.ttt", "rb");
unsigned short stringLength = 0;
fread(&stringLength, sizeof(unsigned short), 1, fp);
char *drumReadString = malloc(sizeof(char) * stringLength);
int count = fread(&drumReadString, sizeof(char), stringLength, fp);
//CRASH POINT
printf("%s\n", drumReadString);
fclose(fp);
解决方案
您做错了,而读。 你已经把与该指针变量,这就是为什么它给分段错误。
我删除它工作得很好,它正确返回你好。
int count = fread(drumReadString, sizeof(char), stringLength, fp);
其他提示
我看到了一些问题,有些是有问题的,有些是风格上的。
- 您应该真正测试以下返回值
malloc
,fread
和fwrite
因为分配可能会失败,并且无法读取或写入任何数据。 sizeof(char)
是 总是 1,不需要乘以它。- 字符数组
"Hello\0"
实际上是7个字节长。您不需要添加多余的空终止符。 - 我更喜欢这个成语
char x[] = "xxx";
而不是指定一个确定的长度(当然,除非您想要一个比字符串长的数组)。 - 当你
fread(&drumReadString ...
, ,你实际上覆盖了 指针, ,而不是它指向的内存。这就是你崩溃的原因。它应该是fread(drumReadString ...
.
的一些提示:
1
一个端接\0
是隐含在任何双引号的字符串,并通过在你结束了两个端增加一个额外的。下面的两个初始化是相同的:
char str1[6] = "Hello\0";
char str2[6] = { 'H', 'e', 'l', 'l', 'o', '\0', '\0'};
所以
char drumReadString[] = "Hello";
就足够了,当它被这样初始化指定数组的大小是任选的,编译器将计算出所需要的尺寸(6个字节)。
2
在写一个字符串,你还不如只写一次过的所有字符(而不是一个字符写一个sizeOfString次):
fwrite(drumCString, sizeOfString, 1, fp);
3
虽然不那么常见的普通台式机的情况下,可以的malloc返回NULL,你会从开发一直检查的结果,因为在嵌入式环境中,越来越NULL不是一个不可能的结果的习惯中受益。
char *drumReadString = malloc(sizeof(char) * stringLength);
if (drumReadString == NULL) {
fprintf(stderr, "drumReadString allocation failed\n");
return;
}
您不写终止NUL,你并不需要但你要想想阅读时添加。即malloc的stringLength + 1块炭,读stringLength字符和在什么已被读取的末尾添加一个\0
。
现在通常的警告:如果你正在写的二进制文件,你在这里做的方式,你有许多不成文的假设,使您的格式很难端口,有时甚至以相同的编译器的另一个版本 - 我见过在编译器版本之间结构变化默认对准。
有些更添加到paxdiablo和AProgrammer - 如果你打算在将来使用malloc,只是做它从一开始走。这是更好的形式和手段,当切换你不会有调试。
此外,我不能完全看到使用无符号短的,如果你正在编写一个二进制文件的规划,考虑unsigned char类型通常是大小字节,使为此目的非常方便。
您只需移除&drumReadString在的fread function.You简单地在该函数中作为内甚mentioned.Because使用drumReadString,drumReadString是array.Array类似于指针,其指向的存储器位置直接