繁体   English   中英

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

[英]Reading and writing in binary file using iteration on C++

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

我在编写时都遇到问题(不确定是否正确):

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++;
    }
}

从对std::getline()使用中可以明显看出, nomePersonagemnomeCriadorstd::string值。 std::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();
}

暂无
暂无

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

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