使用C ++上的迭代在二进制文件中读取和写入

时间:2018-01-09 00:32:33

标签: c++ file binary

我正在做一个涉及系统的功课,该系统将结构保存在二进制文件中,必须(?)使用迭代。

我在写作方面都有问题(不确定是否正确):

void InserirDados () {

    //var created to acknowledge the quantity of items that will be described
    int quantidade;

    cout << "Quantos personagens voce pretende inserir nesta sessao?" << endl;
    cin >> quantidade;

    //allocating memory like it's asked by the teacher
    PersonagemDesenho* objPersonagem = new PersonagemDesenho[quantidade];

    //declaring the flow of data
    ofstream arquivo ("personagens.dat", ios::binary);

    //flush buffer
    cin.ignore ();

    cout << "(A utilizacao de espacos e' permitida para todos os itens a seguir)" << endl;

    //describing items
    for (int i = 0; i < quantidade; i++) {
        cout << " - PERSONAGEM NUMERO: " << i + 1 << endl;

        cout << "Digite o nome do personagem a ser inserido" << endl;
        //getline for getting more than 1 word
        getline(cin, objPersonagem[i].nomePersonagem);

        cout << "Digite o nome do criador do personagem" << endl;
        getline(cin, objPersonagem[i].nomeCriador);

        //writing code
        arquivo.write(reinterpret_cast<const char*> (&objPersonagem[i]), sizeof(PersonagemDesenho));
        }
    cout << "As informacoes serao salvas no arquivo \"personagens.dat\"" << endl;
    //closing file
    arquivo.close();
}

并阅读数据:

void ListaDados () {

    ifstream arquivo ("personagens.dat", ios::binary);
    int i = 0;

    while (???) {
        arquivo.read(reinterpret_cast<const char*> (&objPersonagens[i]) sizeof(PersonagemDesenho))
        i++;
    }
}

1 个答案:

答案 0 :(得分:0)

您使用std::getline()表明nomePersonagemnomeCriador的值为std::stringstd::string是一种动态类型(它包含指向存储在别处的数据的指针)。当它包含动态数据时,您不能按原样写/读结构。您可以自己编写/读取指针,而不是指向的数据。

此问题的解决方案要求在写入时将数据序列化为更平的格式,并在阅读时反序列化数据。

尝试更像这样的东西:

void writeSizeT(ostream &out, size_t value) {
    out.write(reinterpret_cast<char*>(&value), sizeof(value));
}

void writeString(ostream &out, const string &value) {
    size_t len = value.size();
    writeSizeT(out, len);
    out.write(s.c_str(), len);
}

void InserirDados () {
    //var created to acknowledge the quantity of items that will be described
    int quantidade;

    cout << "Quantos personagens voce pretende inserir nesta sessao?" << endl;
    cin >> quantidade;

    //allocating memory like it's asked by the teacher
    PersonagemDesenho* objPersonagem = new PersonagemDesenho[quantidade];

    //declaring the flow of data
    ofstream arquivo ("personagens.dat", ios::binary);

    writeSizeT(arquivo, quantidade);

    //flush buffer
    cin.ignore ();

    cout << "(A utilizacao de espacos e' permitida para todos os itens a seguir)" << endl;

    //describing items
    for (int i = 0; i < quantidade; i++) {
        cout << " - PERSONAGEM NUMERO: " << i + 1 << endl;

        //getline for getting more than 1 word
        cout << "Digite o nome do personagem a ser inserido" << endl;
        getline(cin, objPersonagem[i].nomePersonagem);
        cout << "Digite o nome do criador do personagem" << endl;
        getline(cin, objPersonagem[i].nomeCriador);

        //writing code
        writeString(arquivo, objPersonagem[i].nomePersonagem);
        writeString(arquivo, objPersonagem[i].nomeCriador);
    }

    cout << "As informacoes serao salvas no arquivo \"personagens.dat\"" << endl;

    //closing file
    arquivo.close();

    // freeing memory
    delete[] objPersonagem;
}

size_t readSizeT(istream &in) {
    size_t value;
    in.read(reinterpret_cast<char*>(&value), sizeof(value));
    return value;
}

string readString(istream &in) {
    string value;
    size_t len = readSizeT(in);
    if (len > 0) {
        value.resize(len);  
        in.read(&s[0], len);
    }
    return value;
}

void ListaDados () {
    ifstream arquivo ("personagens.dat", ios::binary);

    size_t quantidade = readSizeT(arquivo);

    //allocating memory like it's asked by the teacher
    PersonagemDesenho* objPersonagem = new PersonagemDesenho[quantidade];

    for(size_t i = 0; i < quantidade; ++i) {
        //reading code
        objPersonagem[i].nomePersonagem = readString(arquivo);
        objPersonagem[i].nomeCriador = readString(arquivo);
    }

    // freeing memory
    delete[] objPersonagem;

    //closing file
    arquivo.close();
}