向文件发出书面结构问题

时间:2012-09-14 13:31:46

标签: c

我在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);
        }

}

输出: 当我打开文件检查我得到:

  • 名称,但附加字符
  • dept ,但附加字符
  • id 我得到了一些垃圾值。

请告诉我解决此问题的方法。

3 个答案:

答案 0 :(得分:1)

  

输出:当我打开文件检查我得到:

     
      
  • 我得到的名字,但有其他字符
  •   
  • dept我得到了但是还有其他角色
  •   
  • id我得到了一些垃圾价值。
  •   

fwritesizeof(struct stud)个字节写入文件,它不关心这些字节包含的内容。由于您尚未初始化s,因此namedept数组包含未指定的数据,并且未被输入覆盖的那些字节(包括0终结符)保留其垃圾值,那些也被写入文件,因此namedept之后的其他字符。 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个字符的名称或部门,则可能会出现缓冲区溢出。