1

我为学生创建了一个班级。这是课堂。

class student
{
  int rollno,marks;
  char name[20];


 public:
    void show();
    void get();
    int filecreate(const string &,fstream &);
    int fileopen(const string &,fstream &);
    static int add(const student &,fstream &);
    static int read(const student &,fstream &,int);
    static int update(const student &,fstream &,int);
    int showall(fstream &);
    int view(fstream &,int );
    int adddummy(fstream &);
};

这是我在二进制文件中写入记录的 add 方法。

int student::add(const student &s,fstream &fp)
{
        fp.seekp(0, ios::end);
        if(fp.write((char*)&s,sizeof s))
            return 1;
        return 0;
}

如果我写入对象 s 的值,写入文件的值是什么。是否只有rollno、标记和名称(仅限数据成员?)。现在我想为 fstream 添加一个成员。添加成员后,如果我写入文件,哪些数据将写入文件(fstream 值也会写入文件吗?)

4

4 回答 4

4

我认为您首先要实现的是类实例的序列化。

这个问题及其答案可能对此有所帮助。特别是这个链接(在最高评价的答案中提供)到 C++ 序列化的常见问题解答可能值得您考虑。

于 2011-11-02T10:29:08.313 回答
2

写入文件的值是什么。是否只有rollno、标记和名称(仅限数据成员?)。

就您而言-是的,因为该班级没有vtable或父母。

如果我写文件,什么数据会写入文件(fstream 值也会写入文件吗?)

是的。fstreamvalues 对你来说完全没有意义,但它们会被写入。但是,如果您以相同的方式读取存储的值,则对象将变得不可用,因为 fstream 可能包含句柄、指针等 - 在第二次运行时将无效的数据。

此方法也存在二进制兼容性问题——每次添加或更改类成员时,您之前保存的数据都会变得不可用。

于 2011-11-02T08:07:48.127 回答
1

我不确定是否理解您的问题,但如果您在该成员之后添加数据成员,fstream foo;也会被写入。然而,写 a通常是没有意义的,因为(至少在 Unix 系统上)打开的文件在进程结束后不会保持打开状态。您应该问自己,当您再次读取该数据时会发生什么(以及您将如何读取它)。阅读您以这种方式编写的内容是没有意义的。nameclass studentfstreamfstream

并且当新手完成时,写入二进制数据通常是一个错误。关键是二进制数据非常脆弱。例如,在您的示例中,您稍后可能希望将 的大小增大name[20]到某个更高的值(例如name[32]),因为您认为有些人的名字很长。如果您这样做了,并且您已经以二进制形式为您的学校编写了所有数据(当应用程序使用时name[20]),您将无法使用名称已增长到的应用程序将其读回(无需编码转换例程)name[32].

这就是为什么通常值得使用一些更高级别的工具(例如 MySQL 等数据库)或使用XMLJSONYAML等标准以文本形式表示持久数据。当然它也有缺点:读写数据的代码更复杂,执行更慢。但是文本数据更容易调试,作为程序员你可以用普通的编辑器来查看。

于 2011-11-02T08:11:34.110 回答
0

我在评论中提到的GDBM库是一个 GNU 数据库函数库,它使用可扩展散列,工作方式类似于标准 UNIX dbm;它管理键(任意字节的任意序列)与值(同样,任意字节的任意序列)的索引关联。

除了使用 JSON、XML 或 YAML 等文本序列化格式之外,您还可以使用像s11n这样的 C++ 序列化库

于 2011-11-02T10:58:36.263 回答