【问题标题】:How to print a string from an object?如何从对象打印字符串?
【发布时间】:2021-12-13 09:50:41
【问题描述】:

我尝试使用以下代码将对象写入 dat 文件:

#include<iostream>
#include<fstream>
#include<string>
#include<string.h>

using namespace std;
class Student
{ //data members
    int adm;
    string name;
public:
    Student()
    {
        adm = 0;
        name = "";
    }
    Student(int a,string n)
    {
        adm = a;
        name = n;
    }
    Student setData(Student st) //member function
    {
        cout << "\nEnter admission no. ";
        cin >> adm;
        cout << "Enter name of student ";
        cin.ignore();
        getline(cin,name);
        st = Student(adm,name);
        return st;
    }

    void showData()
    {
        cout << "\nAdmission no. : " << adm;
        cout << "\nStudent Name : " << name;
    }

    int retAdmno()
    {
        return adm;
    }
};

/*
* function to write in a binary file.
*/
void demo()
{
    ofstream f;
    f.open("student.dat",ios::binary);

    for(int i = 0;i<4;i++)
    {
        Student st;
        st = st.setData(st);
        f.write((char*)&st,sizeof(st));
    }
    f.close();
    ifstream fin;
    fin.open("student.dat",ios::binary);
    Student st;
    while(!fin.eof())
    {
        fin.read((char*)&st,sizeof(st));
        st.showData();
    }
}
int main()
{
    demo();
    return 0;
}

但是当我执行演示函数时,我从“student.dat”中得到了一些垃圾值 文件。我正在创建一个数据库并想要获取记录,但我无法获取 dat 文件中的所有记录。

请提出解决方案

【问题讨论】:

  • Student Student::setData(Student st) 是一个非常奇怪的成员函数。它是一个成员函数,因此您需要在现有的Student 对象上调用它。您需要传递第二个Student 对象作为参数st,只是为了让它被忽略和覆盖。最后返回第三个 Student 对象。
  • 这是一个常见问题解答。您不能使用 fread/fwrite 或 fstream::{read,write} 将 std::strings 转储到磁盘。发明一种适当的序列化格式或使用现有的。 Using fread/fwrite for STL string. Is it correct?
  • 你不能像 std::string 这样存储非平凡的对象。阅读有关序列化的信息,或定义更合适的类型。
  • 建议:如果您的实际目标是存储学生数据,请尝试提供 JSON 或某种数据库或某种其他文本格式。

标签: c++ windows c++17 file-handling


【解决方案1】:

您不能以二进制模式将复杂数据类型写入文件。它们里面有一些额外的变量和函数,你不知道也看不到。这些数据类型有一些内部状态或上下文相关。因此,您不能以二进制形式存储然后在其他地方重用它。那永远都行不通。

解决办法是序列化/反序列化。

这听起来很复杂,但你的情况根本不是这样。这基本上意味着您结构中的所有数据都应转换为纯文本并放入文本文件中。

为了读回数据,它会首先被读取为文本,然后转换为你的内部数据结构。

默认方法是覆盖插入器&lt;&lt; 运算符和提取器&gt;&gt; 运算符。

查看修改后的代码中的简单示例:

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


class Student
{ //data members
    int adm;
    std::string name;
public:
    Student()
    {
        adm = 0;
        name = "";
    }
    Student(int a, std::string n)
    {
        adm = a;
        name = n;
    }
    Student setData(Student st) //member function
    {
        std::cout << "\nEnter admission no. ";
        std::cin >> adm;
        std::cout << "Enter name of student ";
        
        std::getline(std::cin>> std::ws, name);
        st = Student(adm, name);
        return st;
    }
    void showData()
    {
        std::cout << "\nAdmission no. : " << adm;
        std::cout << "\nStudent Name : " << name;
    }
    int retAdmno()
    {
        return adm;
    }
    friend std::ostream& operator << (std::ostream& os, const Student& s) {
        return os << s.adm << '\n' << s.name << '\n';
    }
    friend std::istream& operator >> (std::istream& is, Student& s) {
        return std::getline(is >> s.adm >> std::ws, s.name);
    }
};

/*
* function to write in a binary file.
*/
void demo()
{
    std::ofstream f("student.dat");
    for (int i = 0; i < 4; i++)
    {
        Student st;
        st = st.setData(st);
        f << st;
    }
    f.close();
    std::ifstream fin("student.dat");
    Student st;
    while (!fin.eof())
    {
        fin >> st;
        st.showData();
    }
}
int main()
{
    demo();
    return 0;
}

【讨论】:

    猜你喜欢
    • 2018-07-09
    • 1970-01-01
    • 1970-01-01
    • 2016-03-31
    • 2023-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多