【问题标题】:C++ How can i get all line in binary files?C++ 如何获取二进制文件中的所有行?
【发布时间】:2019-04-21 02:01:27
【问题描述】:

我的代码在下面。

int main() {
    Employee* employee = new Employee();
    cout << "Creating File..." << endl;
    fstream file("deneme1.txt",ios::out|ios::binary|ios::ate);
    for(int i=0;i<10;i++){
        if(i<4){
            string name;
            float salary;
            int yearHired;
            cout<<"Enter Name: ";
            cin>>name;
            cout<<"Enter Salary: ";
            cin>>salary;
            cout<<"Enter Year Hired: ";
            cin>>yearHired;
            employee->set_id(i);
            employee->set_name(name);
            employee->set_salary(salary);
            employee->set_yearHired(yearHired);
            file.write((char*)&employee,sizeof(employee));
            file.close();
             }

         }
        file.open("deneme1.txt",ios::in|ios::out|ios::binary);

        file.seekg(0);


        while((file.read((char*)&employee,sizeof(employee)))) {
   cout << employee->get_id();
}



}

我有一个名为“deneme1.txt”的二进制文件。我将四个对象记录到“deneme1.txt”。我想在while 循环中获取所有“deneme1.txt”行,但我只能得到最后一行。(所以输出是 “正在创建文件... 3" )

如何获取文件中的所有行?也许文件只有一个对象?

下面是我的班级

class Employee
{
private:
    string name; 
    int id;
    float salary;
    int yearHired;

public:
    void set_name(string n)
    {
        this->name = n;
    }
    void set_id(int i)
    {
        this->id = i;
    }
    string get_name()
    {
        return name;
    }
    int get_id()
    {
        return id;
    }


    void set_salary(float s)
    {
        this->salary = s;
    }

    float get_salary()
    {
        return salary;
    }

    void set_yearHired(int y)
    {
        this->yearHired = y;
    }

    int get_yearHired()
    {
        return yearHired;
    }


};

我希望输出为“0 1 2 3”

【问题讨论】:

  • 二进制文件??如何在二进制文件中定义 line ?请注意解释。
  • 显示您的班级标题。如果 name 是 std::string 你不能这样做。
  • 我的二进制文件名为“deneme1.txt” 通常二进制文件没有.txt 扩展名。
  • @BatuhanÖzkan -- 这些代码都不起作用,所以问“为什么我不能用 id 做 x”是无效的。如果要证明,sizeof(Employee) 等于什么?不管name 给你的size() 是什么,它都是一样的。那么如果name 是 1,000 个字符,这应该如何工作?
  • 我该如何解决这个问题? -- 你的文件的布局是什么?换句话说,另一个应用程序如何能够读取您的文件并从文件中重新创建员工?这是您应该弄清楚的第一步——它与编码无关。一旦你知道了这一点,那么它是二进制文件、文本文件等都没有关系。简而言之,这就是对象序列化——谷歌就可以了。

标签: c++ file binary


【解决方案1】:

经过一些清理后,这不应该有任何未定义的行为。

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

class Employee {
private:
    std::string name;
    int id;
    float salary;
    int yearHired;
public:
    Employee(const std::string &name, int id, float salary, int yearHired) : name(name), id(id), salary(salary),
                                                                             yearHired(yearHired) {}
    Employee(Employee const&) = delete;
    Employee& operator=(Employee const&) = delete;
    int get_id() const {
        return id;
    }
};

int main() {
    std::cout << "Creating File..." << std::endl;
    {
        std::ofstream file("deneme1.txt", std::ios::out | std::ios::binary | std::ios::ate);
        std::string name;
        for (int i = 0; i < 4; i++) {
                float salary;
                int yearHired;
                std::cout << "Enter Name: ";
                std::cin >> name;
                std::cout << "Enter Salary: ";
                std::cin >> salary;
                std::cout << "Enter Year Hired: ";
                std::cin >> yearHired;
                Employee employee(name, i, salary, yearHired);
                file.write((char *) &employee, sizeof(employee));
        }
    }  // file.close();

    std::ifstream file("deneme1.txt", std::ios::in | std::ios::binary);

    char* employeeData = new char[sizeof(Employee)];
    {
        const Employee &employee = *reinterpret_cast<const Employee *>(employeeData);
        while ((file.read((char *) &employee, sizeof(employee)))) {
            std::cout << employee.get_id();
        }
    }
    delete[]employeeData;

    return EXIT_SUCCESS;
}

【讨论】:

  • 但是输出是0123而不是0 1 2 3
  • 你不能像 fwritestruct 那样包含 string。您将需要序列化数据而不是字符串对象。
  • @BoR -- 你没有看到我关于为什么这永远行不通的评论吗? sizeof(Employee) 在 ideone 上运行时为 48,无论 name 中有多少个字符。所以这个解决方案不是解决方案。
  • @PaulMcKenzie 是的,看到了。但只要您不触摸 std::string 成员,这“有效”。就目前而言,它将适用于 POD 数据类型。但是,确实,如果您真的想要一种二进制格式,则需要对其进行定义,而我没有花时间去做。
  • @RetiredNinja 正确,这就是我不碰那个成员的原因,也是我必须将数据区域分配为 char 数组以避免运行其构造函数和析构函数的另一个原因。 reinterpret_cast 应该暗示这里有些棘手。
猜你喜欢
  • 2021-09-26
  • 2012-03-19
  • 2023-01-12
  • 2015-06-07
  • 1970-01-01
  • 1970-01-01
  • 2022-06-22
  • 2011-01-26
  • 1970-01-01
相关资源
最近更新 更多