0

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

}

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

  • 名称但带有附加字符
  • 部门,但有额外的字符
  • id 我得到了一些垃圾值。

请让我知道解决此问题的方法。

4

3 回答 3

1

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

  • 我得到的名字,但有额外的字符
  • 我得到了部门,但有额外的字符
  • 我得到了一些垃圾值。

将字节fwrite写入sizeof(struct stud)文件,它不关心这些字节包含什么。由于您尚未初始化snameanddept数组包含未指定的数据,并且那些未被输入覆盖的字节(包括 0 终止符)保留它们的垃圾值,这些也被写入文件,因此和之后的附加name字符dept. 以id二进制表示形式写入文件,当它(试图)被编辑器解释为文本时,看起来像垃圾。

但是,您应该防止输入写入数组边界之外,因此您应该限制scanf格式中字符串的长度,%19s而不是%s确保最多 19 个字符被扫描到 20 字节数组中,为 0 终止符留出位置.

于 2012-09-14T13:49:21.747 回答
0

你必须序列化你的数据,在你的 char[] 末尾添加 '\0'。

但是二进制模式下的 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
    }
于 2012-09-14T13:48:59.207 回答
0

利用

memset(&s, 0, sizeof(stud));

在写入字符串之前先对数据进行消毒,这样当您尝试打印它时它就不会显示出来。

id 是完全垃圾的原因是因为即使它被 scanf 存储为文本,您也以二进制形式写入文件。它也应该是一个字符串。

另请注意,由于缓冲区如此短,如果有人键入的名称或部门长度超过 20 个字符,您很可能会出现缓冲区溢出。

于 2012-09-14T13:49:56.637 回答