【问题标题】:Reading and writing in binary file using iteration on C++在 C++ 上使用迭代读取和写入二进制文件
【发布时间】:2018-01-09 00:32:32
【问题描述】:

我正在做一项涉及将结构保存在二进制文件中的系统的作业,这是必要的(?)使用迭代。

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

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

【问题讨论】:

  • 你有没有先尝试过更简单的事情?可以读写onePersonagemDesenho吗?你能读写一个int吗?
  • 我已经做了很多文本文件练习,但这是我第一次接触二进制文件,因为我们没有任何关于它们的练习。
  • 你的教科书有提到二进制文件吗?您是否考虑过 Google 搜索“C++ 写入二进制文件”?
  • 对于我大学课程第一阶段的课程作业来说,序列化似乎太复杂了。我可以 99% 的自信地说,老师们没有问这个问题。
  • 我当然做了研究,我今天已经连续研究了大约 9 到 10 个小时。没有研究,我不可能写出这段代码。我为这个特定问题找到的最好的方法是这个链接:pt.stackoverflow.com/questions/214789/… 但它使用的术语我从未见过,老师们也从未说过。

标签: c++ file binary


【解决方案1】:

从您对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();
}

【讨论】:

  • 非常感谢您的回答!你有什么推荐给我的,这样我就可以完全理解你做了什么?就像一本书或类似的东西。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-03
  • 1970-01-01
  • 2019-03-27
  • 1970-01-01
相关资源
最近更新 更多