如何将结构存储到文件中

时间:2016-02-02 17:30:43

标签: c++

我试图让这段代码在过去一周没有成功。实际上它是一团糟,我不知道哪种方式运行。这是我的代码的一部分:

void mfy_st(ifstream& FILE_E, ofstream& FILE_O)
{
    int option = 0;
    double amount;
    char unit;
    currency curr;

    cout<< "1- Enter cash \n"<<"2- Withdraw \n";
    cin>>option;

    switch(option)
    {
        case 1:
            cout<<"Enter the amount you would like to enter, followed by the unit: \n";
            open_file();
            cin>>amount>>unit;
            curr.amount = amount;
            curr.unit = unit;
            FILE_E<<curr.amount<<curr.unit;
            FILE_E.close();
            break;
        case 2: cout<<"Enter the amount you would like to withdraw, followed by the unit: \n";
            open_file();
            cin>>amount>>unint;
            curr.amount = amount;
            curr.unit = unit;
            FILE_O<<curr.amount<<curr.unit;
            FILE_O.close();
            break;
        default:
            cout<<"Option invalid";
            break;
    }
}

我在写文件时遇到问题。并且编译器抛出错误:'operator&lt;&lt;'不匹配(操作数类型是'std :: ifstream {aka std :: basic_ifstream}'和'double')。

我知道代码有点乱,我会在程序运行时修复它! 希望你能帮帮我。

3 个答案:

答案 0 :(得分:2)

序列化

将结构或类写入文件称为序列化。有许多库可以为您执行此操作,例如Boost

选择格式

有许多数据格式可用于您的数据内容,例如XML,INI,二进制,CSV或其他文本格式。每个人都有不同的优点和缺点。例如,二进制方法是内部表示的镜像,可能在所有平台上都无效。 XML语言更冗长,但可以在许多平台上读取并由文本编辑器读取。

POD与非POD内容

使用二进制格式时,如果只包含POD(普通旧数据)类型,则只能编写整个结构。任何使用指针的内容(例如std::stringstd::vector)都无法正确复制,因为无法保证在再次调用程序时程序将具有相同的内存地址。此外,无法保证其他平台将使用相同的寻址方案(例如,某些平台可能使用分段内存寻址与线性)。

让结构写出其成员

除非你有一个序列化库,否则我建议在结构或类中实现将成员写入流(输出)并从流中读取(输入)的方法。结构知道其成员的详细信息,并应遵循数据隐藏的概念。

填充:结构的大小?=成员的总和

允许编译器在成员之间添加间距,通常用于对齐目的。如果您遵循协议,由于填充,写入结构可能不遵循协议。在这种情况下,首选方法是单独读取或写入每个成员以避免填充问题(Little-Endian和Big-Endian问题也可以这样处理)。

摘要

在调试时,选择文本编辑器可读取的数据格式。只在必要时才根据需要更改格式(如效率或大小)。数字的二进制(内部表示)比它们的文本表示更难调试,尤其是浮点数。

读取和写入数据结构的概念称为序列化。已存在许多执行此功能的库。如果要搜索数据,可能需要考虑使用数据库。

答案 1 :(得分:1)

您的代码有两个问题:

  1. 您没有编写适当的分隔符:

    DataTable dt_grouped_by = dt_data.AsEnumerable()
                              .GroupBy(r => new { LOCNR = r["LOCNR"], DEPTNR = r["DEPTNR"] })
                              .Select(g => g.OrderBy(r => r["CODE"]).First())
                              .CopyToDataTable();
    
  2. 您使用错误的运算符来读取数据:

     FILE_O << ' ' << curr.amount << ' ' << curr.unit << std::endl;
    
  3. 此外,您应该考虑为 FILE_E >> curr.amount >> curr.unit; // ^^ ^^ 提供I / O运算符的实现:

    struct currency

    这适用于所有类型的流。

答案 2 :(得分:0)

尽管这是一个微不足道的案例,但您可能需要考虑通过运算符重载来实现这一点,如here所述。

这样,功能将被干净地封装掉,并且使用此结构不会影响调用代码。