简体   繁体   English

将结构成员写入二进制文件并在C ++中使用fstream读取它们

[英]Writing structure members into binary and reading them in using fstream with C++

Still new to the world of C++, and the following question is because of a homework assignment! 在C ++领域还是一个陌生的人,下面的问题是由于作业所致! I have not found much in the way of help searching through previously answered questions or Google, does not mean I have not missed it. 我在搜索以前回答的问题或Google方面没有找到太多帮助,但这并不意味着我没有错过。

The Homework's Goals: 1.) Take user input information and store it in a binary file. 作业的目标:1.)获取用户输入的信息并将其存储在二进制文件中。 2.) Read that data back in later. 2.)稍后再读回该数据。

I have an array of up to 10 structures, the struct takes on char array of a user name, char array of user phone number, and a float salary. 我有最多10个结构的数组,该结构采用用户名的char数组,用户电话号码的char数组和浮动工资。 When I enter a few test cases, the file writes, I am assuming correctly. 当我输入一些测试用例时,该文件将写入,我假设是正确的。 When I go to read the values in, the first name prints out nicely as does the first phone number. 当我去读取值时,第一个电话号码和第一个电话号码都很好地打印了出来。 The float gives me -4013602080 not matter what value I had entered into the test case. 无论我在测试用例中输入了什么值,浮点数都给我-4013602080。 From there it goes downhill. 从那里开始下坡。 I am trying this using . 我正在尝试使用。 My question boils down to two parts, am I "properly" writing the structure members to the file, and how do I read in floats from binary? 我的问题可分为两部分,我是“正确地”将结构成员写入文件中,如何从二进制中读取浮点数? (or should would it be advantageous to use fopen and fclose?) Hints or references would be wonderful. (或者使用fopen和fclose会有利吗?)提示或引用将是很棒的。

header 标头

//my header
#ifndef USERS_H
#define USERS_H


#include <iostream>
#include <cstring>
#include <cstdlib>
#include <limits>
#include <iomanip>

const int arsize=20;
using namespace std;
struct emp
{
    char name[arsize];
    char phone[arsize];
    float salary;
};
class Users
{
private:
    //const int arsize=20;
    int choice, num_of_names;
public:
    Users();
    void menu();
    void enter(emp*pt, int n);
    void print_all(emp*pt);
    void print_condition(emp*pt);
    void end_phone_array(emp*pt);
    void bubble_sort(emp*pt);
    void selection_sort(emp*pt);
    void raise(emp*pt);
            void file_store(emp*pt);
    void file_read(emp*pt);

};
#endif USERS_H_

Here is the necessary parts from the source file I believe: 这是我相信的源文件中的必要部分:

void Users::enter(emp*pt, int n)
{
    extern int gl,count,f;
    if(gl+n>10)
    {
        cout<<"Memory Full!\n";
    }
    else
    {
        for (int i=count;i<f+n;i++)
        {
            gl++;
            cout<<"Enter user #"<<i+1<< " name(no more than 20 characters)\n";
            cin.get();
            cin.getline(pt[i].name, arsize);//.get();
            cout<<"Enter user #"<<i+1<< " phone #\n";
            cin.getline(pt[i].phone, arsize);//.get();
            cout<<"Enter user #"<<i+1<< " salary\n";
            (cin>>pt[i].salary);//.get();
        }
        count=gl;
        f=gl;
    }
}
void Users::file_store(emp* pt)
{
    //ifstream::pos_type size;
    extern int gl;
    //float test;
    //ofstream Testfile ("C:\\Users\\Ian\\Desktop\\Programming\\C++\\data.bin", ios::out| ios::binary);  //for personal computer use
    ofstream Testfile ("data.bin", ios::out | ios::binary);
    for (int i=0; i<gl;i++)
    {
        Testfile.write((char*)&pt[i].name, sizeof(pt));
        Testfile.write(pt[i].phone, sizeof(pt[i].phone));
        Testfile.write((char *)&pt[i].salary, sizeof(pt[i].salary));
    }
}
void Users::file_read(emp*pt)
{
    //extern int gl;
    struct TEST
    {
        char n_array[20];
        char p_array[13];
        float salary;
    };
    TEST test[20];
    for (int i=0;i<20;i++)
    {
        test[i].n_array[0]='\0';
        test[i].p_array[0]='\0';
        test[i].salary=0.0;
    }
    /*ifstream::pos_type size;
     * char *memblocktest;*/
    ifstream test_in ("data.bin", ios::in | ios::binary);
    for(int i=0;i<10;i++)
    {
        if(test_in.is_open())for(int i=0;i<10;i++)
        {
            test_in.read((char*)&test, sizeof(test));
            cout<<test[i].n_array<<"\n";
            cout<<test[i].p_array<<endl;
            cout<<"$"<<test[i].salary<<endl;
        }
        else
            cout<<"Don't know what I am doing!\n";
    }


}

and here is the main file 这是主文件

#include "stdafx.h"
#include "users.h"
#include <iostream>
#include <cctype>
#include <limits>
#include <iomanip>
#include <cstring>
using namespace std;


extern int gl=0, count =0, f=0;
int main()
{
    Users Test;
    std::cout.setf(std::ios::fixed);
    std::cout.precision(2);
    emp*test=new emp[10];
    Test.menu();
    int choice, num_of_names;
    while(1)
    {
        if(!(cin>>choice))
        {
            cin.clear();
            cin.ignore(numeric_limits<streamsize>::max(),'\n');
            cout<<"ERROR!\n";
        }
        else
            break;
    }
    while(choice!=9)
    {
        switch(choice)
        {
            case 1:{cout<<"How many users will you enter?\n";
                    cin>>num_of_names;
                    Test.enter(test, num_of_names);
                    Test.end_phone_array(test);
                    break;}
            case 2:{Test.print_all(test);
                    break;}
            case 3:{Test.print_condition(test);
                    break;}
            case 4:{Test.bubble_sort(test);
                    break;}
            case 5:{Test.selection_sort(test);
                    break;}
            case 6:{Test.raise(test);
                break;}
            case 7:{Test.file_store(test);
                    break;}
            case 8:{Test.file_read(test);
                break;}
            default:{"Bad Choice..........\n";
                     break;}
        }
        Test.menu();
        while(1)
        {
            if(!(cin>>choice))
            {
                cin.clear();
                cin.ignore(numeric_limits<streamsize>::max(),'\n');
                cout<<"ERROR!\n";
            }
            else
                break;
        }
    }
    delete [] test;
    //system("Pause");
    return 0;
}

I imagine there are many things I could improve, but for now I would like to figure binary part out. 我想我有很多可以改进的地方,但是现在我想弄清楚二进制部分。 Any hints are much appreciated. 任何提示都非常感谢。 Thanks! 谢谢!

This looks wrong: 这看起来是错误的:

void Users::file_store(emp* pt)
{
    // etc...

        Testfile.write((char*)&pt[i].name, sizeof(pt));
        Testfile.write(pt[i].phone, sizeof(pt[i].phone));
        Testfile.write((char *)&pt[i].salary, sizeof(pt[i].salary));

In the first line, you're storing a name field, but you're using sizeof(pt) as the size, where the size is actually the size of a pointer value. 在第一行中,您存储的是名称字段,但是您使用sizeof(pt)作为大小,其中大小实际上是指针值的大小。 You're also taking the address of the name array (a char** ) and casting it as a char* 您还需要获取名称数组的地址( char** )并将其强制转换为char*

To fix: 修理:

Testfile.write(pt[i].name, sizeof(pt[i].name));
Testfile.write(pt[i].phone, sizeof(pt[i].phone));
Testfile.write((char *)&pt[i].salary, sizeof(pt[i].salary));

Actually, you might not need to do these fields individually (unless you're trying to conform to an ordering that is different to the structure) because the structure does not have any dynamic data. 实际上,由于该结构没有任何动态数据,因此您可能不需要单独处理这些字段(除非您试图遵循与该结构不同的顺序)。 You can store the entire record in one hit: 您可以将整个记录存储在一个匹配中:

Testfile.write((char*)&pt[i], sizeof(struct emp));

Even better, you can store the entire array in one hit and avoid looping: 更好的是,您可以将整个数组一键存储,避免循环:

Testfile.write((char*)pt, gl * sizeof(struct emp));

Similarly for reading... Note that you might want to store the value of gl in the file too, so you know how many records it contains. 与读取类似。请注意,您可能也希望将gl的值存储在文件中,因此您知道它包含多少条记录。 Or if you want to be slightly more arcane, you could check the file size and divide sizeof(struct emp) into it to infer the number of records. 或者,如果您想变得更加神秘,则可以检查文件大小,然后将sizeof(struct emp)划分为文件大小以推断记录数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM