在 C++ 中从文本文件读/写结构

read/write struct from text file in c++

提问人:adam101 提问时间:12/27/2017 更新时间:12/28/2017 访问量:9549

问:

我已经用这段代码被困在同一个地方有一段时间了。最后决定在网上问。任何帮助将不胜感激。

我已经创建了一个结构体,并且能够将数据添加到结构体中,但仍然不确定我是否遵循了正确的方法。主要问题在于当我尝试从文本文件中读取数据时。

我似乎收到一个错误说:

错误 C2678:二进制“>>”:未找到使用左手的运算符 类型为“std::ifstream”的操作数(或没有可接受的转换)

结构:

struct bankDetails              //structure for bank details
{
    int acc_number;
    double acc_balance;
    double deposit_amt;
    double withdraw_amt;
    double interest_rate;
    //char acc_type;


};


struct CustDetails                     //structure for account details
{
    string cust_name;
    string cust_pass;
    bankDetails bankAccounts[99];
};

这是我编写的从文件中读取的代码。

CustDetails loadDataFromFile ()
{
    CustDetails x;
    ifstream  dimensionsInfile; 
    dimensionsInfile.open ("storage.txt");
    for (int i=0; i < 2; i++)                                                               
    {   // write struct data from file  
        dimensionsInfile>>
        &x.bankAccounts[i].acc_balance>>
        &x.bankAccounts[i].acc_number>>
        &x.cust_nam>>
        &x.cust_pass>>
        &x.bankAccounts[i].withdraw_amt>>
        &x.bankAccounts[i].deposit_amt>>
        &x.bankAccounts[i].interest_rate>>
        cout<<"Data loaded"<<endl;
    } 
    return x;

}

要写入文件的代码:

void details_save(int num,CustDetails x)
{

    string  filePath = "storage.txt";                                                                               
    ofstream  dimensionsOutfile;                                                                    

    dimensionsOutfile.open ("storage.txt");                                             
    if (!dimensionsOutfile)
        {
            cout<<"Cannot load file"<<endl;
            return ;
        }
    else
        {
            for (int i=0; i < num; i++)                                                             
                {   // write struct data from file  
                    dimensionsOutfile<<
                    &x.bankAccounts[i].acc_balance<<
                    &x.bankAccounts[i].acc_number<<
                    &x.cust_name<<
                    &x.cust_pass<<
                    &x.bankAccounts[i].withdraw_amt<<
                    &x.bankAccounts[i].deposit_amt<<
                    &x.bankAccounts[i].interest_rate<<
                    cout<<" Customer 1 stored"<<endl;
                }
            cout <<"All details have been successfully saved"<<endl;
            dimensionsOutfile.close();
        }

}

部分主要功能:

#include "stdafx.h"
#include <string>
#include <string.h>
#include <ctime>
#include <fstream>
#include <sstream>
#include <iostream>
#include <iomanip>

int main()

{
    int maxNum;
    CustDetails c;
    c = loadDataFromFile(); //loads data from the file

    {
            //This part adds and changes values
    }

    details_save(maxNum, c); //saves data back to the file
        return 0;
}

我是C++的初学者,任何帮助将不胜感激。 干杯!!

C 可视化-C++ 结构 IOSTREAM IFSrem

评论

1赞 drescherjm 12/27/2017
您正在将指针保存在文件中,而不是实际数据中。
0赞 Dietmar Kühl 12/27/2017
眼前的问题是,您通过指针将参数传递给各个字段。删除 : 输入操作器通过引用获取值。...而且,最重要的是:你总是需要在读取操作后检查*它是否成功(如果你只是学习了最后一点,你就取得了巨大的飞跃)。&

答:

1赞 Basile Starynkevitch 12/27/2017 #1

阅读有关文件格式的信息。您可能需要指定您的(在纸上...),然后您可以为该规范使用一些 EBNF 符号。

您当前的代码可能滥用了运算符>>运算符<<。你不想在文件上写指针(即使你在技术上可以),因为再次读取它们毫无意义(因为 ASLR,并且因为地址不能保证在一次运行到下一次运行时保持不变,或者从一个可执行文件到你的程序明天略有改进)。

你可能想做一些二进制 IO(但我不建议这样做)。然后,您将使用一些二进制输入函数(如 std::istream::read)来读取记录(例如一些 POD)。但是你不能(有意义地)对复杂类(例如 your )执行二进制 IO,其中包含非 POD 数据(例如 -s)。structCustDetailsstd::string

实际上,数据往往比软件读写数据更重要。因此,使用一些更灵活的数据格式是有意义的(例如,您希望在两年内能够让改进版本的代码读取由某些版本代码编写的一些数据)。

因此,通常最好使用一些文本格式(您需要定义和记录它)。您可以选择一些现有的表达式,例如 JSON、YAMLXML、S 表达式。你会发现许多库可以帮助你(例如,jsoncpp for JSON 等)。或者,您也可以使用自己的解析技术。

你也可以考虑一些数据库,也许像sqlite一样简单。

另请阅读有关序列化应用程序检查点持久性和可移植性的信息。

0赞 deepjyoti30 12/28/2017 #2

在 loadDataFromFile() 中,就在之前

cout<<"";

将“>>”替换为“;”。

我们不能将>>运算符与 cout 一起使用。

尽管有一种更好、更简单的方法来做你正在做的事情。 fstream.h 具有直接写入和读取类或结构对象的功能。

语法如下:

<stream name>.read((char*)<object name>,sizeof(<struct/class name>));

因此,loadDataFromFile 可以简化为:

CustDetails loadDataFromFile ()
{
CustDetails x;
ifstream  dimensionsInfile; 
dimensionsInfile.open ("storage.txt");                                                              
     // write struct data from file  
     dimensionsInfile.read((char*) CustDetails, sizeof(x));   
     cout<<"Data loaded"<<endl;
     return x;
}

类似地,写入函数的写入定义。这将为您节省大量时间和麻烦。