我在C中使用Linux,我正在尝试将结构写入文件。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct stud{
char name[20];
char dept[20];
int id;
};
int main()
{
FILE *fptr;
int fwrt;
struct stud s;
printf("enter student name\n");
scanf("%s",s.name);
printf("enter student department\n");
scanf("%s",s.dept);
printf("enter student ID\n");
scanf("%d",&s.id);
fptr = fopen("tiger","wb");
if(fptr == NULL){
perror("error openning file :");
exit(EXIT_FAILURE);
}
fwrt = fwrite(&s,sizeof(struct stud),1,fptr);
if(fwrt == 0){
perror("error writing file :");
exit(EXIT_FAILURE);
}
// fprintf(fptr, "%d", s1->mark);
if(fclose(fptr) == EOF){
perror("error closing file :");
exit(EXIT_FAILURE);
}
}
输出: 当我打开文件检查我得到:
请告诉我解决此问题的方法。
答案 0 :(得分:1)
输出:当我打开文件检查我得到:
- 我得到的名字,但有其他字符
- dept我得到了但是还有其他角色
- id我得到了一些垃圾价值。
fwrite
将sizeof(struct stud)
个字节写入文件,它不关心这些字节包含的内容。由于您尚未初始化s
,因此name
和dept
数组包含未指定的数据,并且未被输入覆盖的那些字节(包括0终结符)保留其垃圾值,那些也被写入文件,因此name
和dept
之后的其他字符。 id
以二进制表示形式写入文件,当编辑器将其(试图)解释为文本时,它看起来像垃圾。
但是,您应该防止在数组边界外写入输入,因此您应该以{{1}}格式限制字符串的长度,scanf
而不是%19s
确保最多将19个字符扫描到20字节数组中,留下0终结符的位置。
答案 1 :(得分:0)
您必须序列化您的数据,添加&#39; \ 0&#39;到你的char []的末尾。
但是二进制模式下的fwrite对于动态结构来说并不方便,当你可以静态地声明你的结构字段时它会更好,所以在你的情况下它很好。
如果你使用这样的fgets,它会更好,而不是scanf:
#define MAX
if (fgets(s.name, MAX, stdin) == NULL)
{
//do what you want here
}
if (fgets(s.dept, MAX, stdin) == NULL)
{
//do what you want here
}
答案 2 :(得分:0)
使用
memset(&s, 0, sizeof(stud));
在写入字符串之前先对数据进行消毒,以便在您尝试打印时不会显示。
id是完全垃圾的原因是因为即使它被scanf存储为文本,你也像二进制一样写入文件。它应该也应该是一个字符串。
另请注意,如果缓冲区很短,如果有人输入超过20个字符的名称或部门,则可能会出现缓冲区溢出。