【问题标题】:Write to binary file not working写入二进制文件不起作用
【发布时间】:2015-10-22 04:13:49
【问题描述】:

下面的代码编译并成功运行,但在退出时没有写入文件。文件被创建,在选择注册时它会询问所有详细信息并显示消息注册成功。文件customers.data 为空(文件大小为 0kb)。函数write 不会将对象写入文件。代码中的所有内容似乎都是正确的。无法识别错误。请帮忙

主程序:

int main()
{
    int ch;
    Customer cust;
    fstream file;
    file.open("customers.data",ios::out|ios::app|ios::binary);
    if(!file)
    {
        cout<<"\nError Files are missing. Unable to create files\n";
        system("pause");
        exit(1);
    }
    cout << "WELCOME! Press any key to continue.\n\n";
    system("pause");
    do
    {
        system("cls");
        cout<<"\n\n\n";
        cout<<"1->Login"<<endl;
        cout<<"2->Register"<<endl;
        cout<<"3->Exit"<<endl;
        cout<<"Choose An option: ";
        cin>>ch;
        switch(ch)
        {
        case 1:
            if(cust.Login()==true)
            {
                LaunchCustomerMenu();
            }
            else
            {
                cout<<"Incorrect Email/Password\n";
                system("pause");
            }

            break;
       case 2:
        cust.Register();
        file.write((char*)&cust, sizeof(cust)); //does not work
        if(!file.fail()) //still true
        {
            cout<<"\n\nRegistration Successful"<<endl;
            system("pause");
        }
         else
            {
                cout<<"\nTheir was a Error processing your Registration\n";
                system("pause");
            }

            break;
        case 3:
            exit(0);
            break;
        default:
            cout<<"\n\nWRONG OPTION\n";
            cout<<"Choose Again\n\n";
            system("pause");
        }
        cin.ignore();
    }
    while(ch!=3);
    file.close();
    return 0;
}

班级:

class Customer
{
private:
    unsigned int CustomerID;
    string CustomerName;
    string CustomerAddress;
    string CustomerEmail;
    string CustomerPassword;
    unsigned int CustomerPhone;
public:
    Customer();

    void Register();
    bool Login();

    unsigned int getID();
    string getName();
    string getEmail();
    string readPassword();
    unsigned int getPhone();
    unsigned int RandomID();

    void modifyName();
    void modifyAddress();
    void modifyEmail();
    void modifyPassword();
    void modifyPhone();
};

CustomerID 是随机生成的。

函数寄存器:

void Customer::Register()
{
    cout<<"Enter Your Name: ";
    cin.ignore();
    getline(cin,CustomerName);
    cout<<"Enter Your Address: ";
    cin.ignore();
    getline(cin,CustomerAddress);
    cout<<"Enter Your Email: ";
    cin>>CustomerEmail;
    cout<<"Enter A Password: ";
    cin.ignore();
    getline(cin,CustomerPassword);
    cout<<"Enter Your Phone no. :";
    cin>>CustomerPhone;
}

编辑: 根据下面的答案,我添加了对 file.fail() 的检查,但它返回 false 并且 customers.data 为空,即 write 操作无法写入对象。

【问题讨论】:

  • 听起来你应该使用现有的数据库,而不是自己发明。
  • @ThomasMatthews 我已经从头开始编写代码了。
  • 如果这是家庭作业,你别无选择。否则,数据库会编写并调试;这就是为什么你应该使用数据库。

标签: c++ fstream


【解决方案1】:

fstream write 调用返回对自身的引用,因此选项 3 的 if 检查总是会返回 true。您需要调用goodbadfail 函数之一来检查它是否真的成功了。

此外,将对象的实际内容写入任何地方(套接字、磁盘等)通常是个坏主意。您应该查找序列化的概念。这是将类数据写入磁盘的正确方法。

【讨论】:

  • 这是我的学校作业,我不能超越所教的内容,所以我不得不将整个对象数据写入文件。
  • @tango 如果这些是你的限制,那很好。但请记住这一点,以备将来之需。如果您不知道,编译器通常会将额外的数据放入对象的实际内存中(如虚拟表、填充等)。因此,当您将对象写入磁盘时,您也在写入该对象。这对可移植性和可维护性以及许多其他功能来说简直就是地狱。
【解决方案2】:

同样的事情发生在我身上,我设法找到了错误。

当使用传统的char 变量类型声明一个数组来保存字符串值时,它可以正常工作。

他们似乎与字符串库的实现有些问题。即使您在读取值时能够以某种方式将值写入具有字符串数据类型的文件,也会生成运行时错误(SIGSEGV)。我认为该字符串使用指针进行动态变量分配,不适合与文件一起使用。这会生成 SIGSEGV,因为分配的变量空间在运行程序后不再保留在内存中。

【讨论】:

    猜你喜欢
    • 2012-01-16
    • 2015-05-13
    • 2017-06-30
    • 1970-01-01
    • 1970-01-01
    • 2013-05-09
    • 2015-02-22
    相关资源
    最近更新 更多