c++构造函数从文件中获取值并进行赋值

//头文件
#pragma once
#ifndef ACCOUNT_H_
#define ACCOUNT_H_
#include
#include
using namespace std;
typedef struct user_account                     //抽象类外定义一个结构体
{
    string name;
    string IDNumber;
    long long cardNumber;
    string phoneNumber;
    string sex;
    string address;
    string kinds;
    char password[7];
    float balance;
    char* start_time;
}USER;
//抽象类()
class Account                        
{                    
protected:                
    string name;
    string IDNumber;
    string phoneNumber;
    long long cardNumber;
    char password[7];
    float balance;                            
public:
    Account();
    Account(string user_name);
    virtual void changepass() = 0;                    
    virtual int checkAccount() = 0;                
    //virtual bool modifyuser() = 0;                
};
#endif
//cpp文件
Account::Account(string user_name)
{
    fstream customer2;              //customer2是一个二进制文件
    USER Info;
    customer2.open(user_name, ios::in | ios::binary);
    customer2.read((char*)&Info, sizeof(USER));
    if (customer2.fail())
    {
        cout << "未找到您的账户" << endl;
        name = "\0";
        IDNumber = "\0";
        phoneNumber = "\0";
        cardNumber = 0;
        strcpy(password, "\0");
        balance = 0;
    }
    else
    {
        name = Info.name;
        IDNumber = Info.IDNumber;                                                  
        phoneNumber = Info.phoneNumber;
        cardNumber = Info.cardNumber;
        strcpy(password, Info.password);
        balance = Info.balance;
        customer2.close();
    }
}
```c++
//主程序
int main()
{
        char choice1;
        offline  customer, blank;    
    cin >> choice1;
    if (choice1 == '1')
    {
        cout << "输入您的姓名" << endl;
        getline(cin, user_name);
        getline(cin, user_name);
        offline temp(user_name);
        customer = temp;
    }
}
我想在构造函数中打开customer2这个文件并将其中的对应值赋给Account中的成员,这个构造函数应该怎么改呀

构造函数

Account::Account(string user_name)
{
    ifstream customer2(user_name, ios::in | ios::binary);
    if (!customer2.is_open())
    {
        cout << "未找到您的账户。" << endl;
        name = "";
        IDNumber = "";
        phoneNumber = "";
        cardNumber = 0;
        strcpy(password, "");
        balance = 0;
    }
    else
    {
        USER Info;
        customer2.read((char*)&Info, sizeof(USER));
        name = Info.name;
        IDNumber = Info.IDNumber;
        phoneNumber = Info.phoneNumber;
        cardNumber = Info.cardNumber;
        strcpy(password, Info.password);
        balance = Info.balance;
        customer2.close();
    }
}


主程序:

#include "Account.h"
#include "offline.h"
#include <iostream>
using namespace std;

int main()
{
    char choice1;
    string user_name;
    offline  customer, blank;
    cin >> choice1;
    if (choice1 == '1')
    {
        cout << "输入您的姓名" << endl;
        cin.ignore();  // 忽略之前输入的回车符
        getline(cin, user_name);
        Account acc(user_name);
        customer = offline(acc);
    }
}

修改一下构造函数就行了

class Account                        
{                    
protected:                
    string name;
    string IDNumber;
    string phoneNumber;
    long long cardNumber;
    char password[7];
    float balance;                            
public:
    Account();
    Account(const string& user_name); // 带参数的构造函数声明
    virtual void changepass() = 0;                    
    virtual int checkAccount() = 0;                
};


Account::Account(const string& user_name) // 添加 const 引用,防止意外修改参数
{
    fstream customer2(user_name, ios::in | ios::binary); // 使用构造函数初始化
    if (!customer2.is_open()) // 判断文件是否打开成功
    {
        cout << "未找到您的账户" << endl;
        name = "\0";
        IDNumber = "\0";
        phoneNumber = "\0";
        cardNumber = 0;
        strcpy(password, "\0");
        balance = 0;
    }
    else
    {
        USER Info;
        customer2.read((char*)&Info, sizeof(USER));
        name = Info.name;
        IDNumber = Info.IDNumber;                                                  
        phoneNumber = Info.phoneNumber;
        cardNumber = Info.cardNumber;
        strcpy(password, Info.password);
        balance = Info.balance;
        customer2.close();
    }
}


int main()
{
    char choice1;
    string user_name;
    cin >> choice1;
    if (choice1 == '1')
    {
        cout << "输入您的姓名" << endl;
        getline(cin, user_name);
        getline(cin, user_name);
        Account customer(user_name); // 使用带参数的构造函数
    }
}


该回答引用ChatGPT
根据问题描述,需要在Account的构造函数中读取一个二进制文件并将其中的信息赋值给Account的成员变量,可以按照以下步骤修改代码:

1. 将结构体USER的定义移动到Account类中,并将需要赋值的成员变量复制到Account的私有成员变量中。

2. 在Account的构造函数中,打开文件并读取文件中的信息,如果读取失败,则将Account的成员变量设置为默认值; 如果读取成功,则将文件中的信息赋值给Account的成员变量。

3. 为了避免文件读写出错和泄漏,需要在文件读取结束后及时关闭文件。

修改后的代码示例如下:


//头文件
#pragma once
#ifndef ACCOUNT_H_
#define ACCOUNT_H_
#include <string>
#include <iostream>
#include <fstream>

using namespace std;

class Account
{
protected:
string name;
string IDNumber;
string phoneNumber;
long long cardNumber;
char password[7];
float balance;
public:
Account();
Account(string user_name);
virtual void changepass() = 0;
virtual int checkAccount() = 0;
};

typedef struct user_account
{
string name;
string IDNumber;
long long cardNumber;
string phoneNumber;
string sex;
string address;
string kinds;
char password[7];
float balance;
char* start_time;
}USER;

//cpp文件
Account::Account(string user_name)
{
fstream customer2; //customer2是一个二进制文件
USER Info;
customer2.open(user_name, ios::in | ios::binary);
if (customer2.fail())
{
cout << "未找到您的账户" << endl;
name = "";
IDNumber = "";
phoneNumber = "";
cardNumber = 0;
strcpy(password, "");
balance = 0;
}
else
{
customer2.read((char*)&Info, sizeof(USER));
name = Info.name;
IDNumber = Info.IDNumber;
phoneNumber = Info.phoneNumber;
cardNumber = Info.cardNumber;
strcpy(password, Info.password);
balance = Info.balance;
customer2.close();
}
}

int main()
{
char choice1;
string user_name;
cin >> choice1;
if (choice1 == '1')
{
cout << "输入您的姓名" << endl;
cin.ignore();
getline(cin, user_name);
Account customer(user_name);
}
return 0;
}


注意:由于USER的定义转移到Account类中,需要在Account类前加上前置声明,避免编译错误。

您已经在构造函数中打开了文件并读取了数据,但是需要将读取到的数据赋值给Account类的成员变量。可以在构造函数中使用成员初始化列表来实现:

Account::Account(string user_name): name(""), IDNumber(""), phoneNumber(""), cardNumber(0), balance(0)
{
    fstream customer2;
    USER Info;
    customer2.open(user_name, ios::in | ios::binary);
    customer2.read((char*)&Info, sizeof(USER));
    if (customer2.fail())
    {
        cout << "未找到您的账户" << endl;
        strcpy(password, "\0");
    }
    else
    {
        name = Info.name;
        IDNumber = Info.IDNumber;
        phoneNumber = Info.phoneNumber;
        cardNumber = Info.cardNumber;
        strcpy(password, Info.password);
        balance = Info.balance;
        customer2.close();
    }
}


在成员初始化列表中,先将所有成员变量初始化为默认值,然后再根据读取到的数据进行赋值。注意在读取数据之前,password成员变量没有赋值,所以需要在构造函数中初始化。

引用chatGPT作答,在您提供的代码中,构造函数 Account::Account(string user_name) 已经可以打开文件并读取信息。如果您想将这些信息赋值给 Account 类中的成员变量,只需要将文件中的信息与相应的成员变量对应即可。下面是一个修改后的 Account::Account(string user_name) 函数:

Account::Account(string user_name)
{
    fstream customer2;              //customer2是一个二进制文件
    USER Info;
    customer2.open(user_name, ios::in | ios::binary);
    customer2.read((char*)&Info, sizeof(USER));
    if (customer2.fail())
    {
        cout << "未找到您的账户" << endl;
        name = "\0";
        IDNumber = "\0";
        phoneNumber = "\0";
        cardNumber = 0;
        strcpy(password, "\0");
        balance = 0;
    }
    else
    {
        name = Info.name;
        IDNumber = Info.IDNumber;                                                  
        phoneNumber = Info.phoneNumber;
        cardNumber = Info.cardNumber;
        strcpy(password, Info.password);
        balance = Info.balance;
        customer2.close();
    }
}

在修改后的代码中,我们将从文件中读取的信息与 Account 类的成员变量相对应。这样,在实例化 Account 类对象时,构造函数会自动打开文件并将文件中的信息赋值给 Account 类对象的成员变量。

该回答引用于ChatGPT:
您可以在 Account 类的构造函数中添加代码来进行文件读取和成员变量的赋值。具体而言,可以使用文件流对象来打开文件,然后调用 read() 函数将二进制数据读入一个 USER 结构体变量中,最后根据需要将结构体变量中的成员赋给 Account 对象的相应成员变量。

以下是相应的修改代码:

#include <fstream>
#include <cstring>

class Account {
protected:
    string name;
    string IDNumber;
    string phoneNumber;
    long long cardNumber;
    char password[7];
    float balance;

public:
    Account(string user_name) {
        fstream customer2(user_name, ios::in | ios::binary);
        USER Info;
        if (customer2.read((char*)&Info, sizeof(USER))) {
            name = Info.name;
            IDNumber = Info.IDNumber;
            phoneNumber = Info.phoneNumber;
            cardNumber = Info.cardNumber;
            strcpy(password, Info.password);
            balance = Info.balance;
        } else {
            cout << "未找到您的账户" << endl;
            name = "\0";
            IDNumber = "\0";
            phoneNumber = "\0";
            cardNumber = 0;
            strcpy(password, "");
            balance = 0;
        }
        customer2.close();
    }

    virtual void changepass() = 0;
    virtual int checkAccount() = 0;
};

在这个实现中,我们将 fstream 对象的初始化放在了构造函数的参数列表中,这样可以更简洁地创建并打开文件。注意,在读取密码 password 字段时,我们不能直接使用 = 运算符进行赋值,而是需要使用 strcpy() 函数。由于密码字段的大小是 7 字节,因此也可以使用 memcpy() 函数来进行数据拷贝。

需要注意的是,如果读取文件失败,则需要设置成员变量为初始值。在这个实现中,我们使用空字符串 "\0" 和 0 来初始化字符串和数字类型的成员变量,但这不一定是最好的做法。如果您已经在 USER 结构体中为字段设置了默认值,可以考虑直接使用默认值来初始化成员变量。

希望对您有所帮助!

该回答通过自己思路及引用到GPTᴼᴾᴱᴺᴬᴵ搜索,得到内容具体如下。
根据你的代码,构造函数的实现已经基本正确,但是在main函数中创建对象时有一点小问题。建议将以下代码:

offline temp(user_name);
customer = temp;

改为:

offline temp(user_name);
customer = &temp;

这是因为在上面的代码中,temp是一个局部变量,当main函数结束时,temp的生命周期也结束,customer指向的地址将变得不可用,可能会导致不可预期的行为。将customer定义为指针类型,并将其指向temp的地址,可以避免这个问题。

同时,建议在Account的构造函数中添加一些错误处理的逻辑,比如在打开文件失败时输出错误信息并退出程序。

最终的代码应该类似于:

// Account.h
#pragma once
#ifndef ACCOUNT_H_
#define ACCOUNT_H_

#include <string>
#include <iostream>
#include <fstream>

using namespace std;

typedef struct user_account
{
    string name;
    string IDNumber;
    long long cardNumber;
    string phoneNumber;
    string sex;
    string address;
    string kinds;
    char password[7];
    float balance;
    char* start_time;
} USER;

class Account
{
protected:
    string name;
    string IDNumber;
    string phoneNumber;
    long long cardNumber;
    char password[7];
    float balance;
public:
    Account();
    Account(string user_name);
    virtual void changepass() = 0;
    virtual int checkAccount() = 0;
};

#endif

// Account.cpp
#include "Account.h"

Account::Account()
{
    name = "\0";
    IDNumber = "\0";
    phoneNumber = "\0";
    cardNumber = 0;
    strcpy(password, "\0");
    balance = 0;
}

Account::Account(string user_name)
{
    fstream customer2;
    USER Info;
    customer2.open(user_name, ios::in | ios::binary);
    if (customer2.fail())
    {
        cout << "未找到您的账户" << endl;
        name = "\0";
        IDNumber = "\0";
        phoneNumber = "\0";
        cardNumber = 0;
        strcpy(password, "\0");
        balance = 0;
    }
    else
    {
        customer2.read((char*)&Info, sizeof(USER));
        name = Info.name;
        IDNumber = Info.IDNumber;
        phoneNumber = Info.phoneNumber;
        cardNumber = Info.cardNumber;
        strcpy(password, Info.password);
        balance = Info.balance;
        customer2.close();
    }
}

// main.cpp
#include "Account.h"

int main()
{
    char choice1;
    string user_name;
    Account* customer = nullptr;
    cin >> choice1;
    if (choice1 == '1')
    {
        cout << "输入您的姓名" << endl;
        getline(cin, user_name);
        getline(cin, user_name);
        offline temp(user_name);
        customer = &temp;
    }
    return 0;
}

如果以上回答对您有所帮助,点击一下采纳该答案~谢谢

以下内容部分参考ChatGPT模型:
根据提问者的需求,需要在Account类的构造函数中从文件中获取值并进行赋值。在原有的代码基础上,可以将从文件中获取值的部分移植到构造函数中,并根据需要进行修改。具体的实现步骤如下:

  1. 在Account类的构造函数中打开对应的文件,读取文件中的内容并进行赋值。

  2. 需要注意的是,在获取字符串类型的值时,需要使用getline函数读取整行,并且需要将读取的内容转换成string类型。

  3. 在读取完文件中的内容后,需要关闭文件。

下面是修改后的Account类的构造函数的示例代码:

Account::Account(string user_name)
{
    fstream customer2;              //customer2是一个二进制文件
    USER Info;
    customer2.open(user_name, ios::in | ios::binary);
    if (customer2.fail())
    {
        cout << "未找到您的账户" << endl;
        name = "\0";
        IDNumber = "\0";
        phoneNumber = "\0";
        cardNumber = 0;
        strcpy(password, "\0");
        balance = 0;
    }
    else
    {
        customer2.read((char*)&Info, sizeof(USER));
        name = Info.name;
        IDNumber = Info.IDNumber;
        phoneNumber = Info.phoneNumber;
        cardNumber = Info.cardNumber;
        strcpy(password, Info.password);
        balance = Info.balance;
        customer2.close();
    }
}

需要注意的是,这里只是给出了示例代码,具体的实现方式可能需要根据实际情况进行修改。
如果我的建议对您有帮助、请点击采纳、祝您生活愉快

注意两点,
第一,你是如何写入那个文件的?
第二,调试你的程序,看看读取是否正确?

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 这有个类似的问题, 你可以参考下: https://ask.csdn.net/questions/7555297
  • 这篇博客也不错, 你可以看下C++ 不能在构造函数中调用构造函数
  • 除此之外, 这篇博客: c++中字符串常见操作中的 ⑤用函数进行赋值 部分也许能够解决你的问题, 你可以仔细阅读以下内容或者直接跳转源博客中阅读:
    string str1;
    str1.assign("hello");  //str1 = "hello"
    str1.assign("hello world",7); //第二个参数代表只要前五个,空格也占一个位置,str1 = "hello w"
    
    string str2 = "abcdefg";
    str1.assign(str2); //str1 = "abcdefg"
    
    string str1; 
    str1.assign('w',5);  //str1 = "wwwww" ,和上边的那个
    

    注意:用函数赋值时,必须先定义变量,赋值操作不能写在同一行。

    下边的这个就不行,是错误的

    string str.assign("abf"); //错误写法
    
  • 您还可以看一下 malloc老师的c++游戏逆向内存封包课程中的 逆向体系课程介绍小节, 巩固相关知识点

如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^