1

I have class player that contains some attributes. I m filling a file with player's data but i want to assign a new id number every time the function is called in a way that the new player's id will be increased every time. So i made this while loop to read number of players and update the player's new id but this doesn't work and nothing is written in the file.

void Player::create_player()
{
    fstream file;
        Player plyr; string passwordt;
        int aget = 0;
        long int id_nmbert = 0;
        string emailt, ingame_namet, full_namet,yes;
        file.open("player_database.dat", ios::binary | ios::app);

        if (!file.is_open())
            throw exception();
        while (file >> yes)  ///
            id_nmbert++;     ///
        cout << "insert player's full name" << endl;
        cin >> full_namet;
        plyr.full_name = full_namet;
        cout << "insert player's age" << endl;
        cin >> aget;
        plyr.age = aget;
        cout << "insert player's email" << endl;
        cin >> emailt;
        plyr.email = emailt;
        cout << "insert player's password" << endl;
        cin >> password;
        plyr.password = passwordt;
        cout << "insert player's ingame name" << endl;
        cin >> ingame_namet;
        plyr.ingame_name = ingame_namet;
        plyr.id_nmber = id_nmbert;
        file.write((char*)&plyr, sizeof(Player));
        file.close();
}

Tried This but it's even worse.

while (!file.eof())
id_numbert;

There are similar questions but not in c++ :).

  • The accepted answer here is a good way to do it. https://stackoverflow.com/questions/43765881/c-reading-binary-files In particular you can't use >> for reading from binary files, that is for formatted (text) input. – Captain Giraffe May 19 '20 at 23:27
  • @CaptainGiraffe But in that example he works with vectors, i don't. Or maybe i don't really understand the concept. – Yassine Mrabet May 19 '20 at 23:30
  • Still, use read. I also noticed your file is in an error state when you try to write to it. That's why you don't see any output. Lets see if I can flesh out an answer. – Captain Giraffe May 19 '20 at 23:32
  • The content of the .dat file, it's layout and protocol for reading, etc, is critical in doing what you seem to be attempting. None of that data is present in your post, and it should be. – WhozCraig May 19 '20 at 23:41
  • @WhozCraig What do you mean by present ? – Yassine Mrabet May 19 '20 at 23:43
  • @WhozCraig OP is misunderstanding how the binary format works, as illustrated by write(.., sizeof(Player)) – Captain Giraffe May 19 '20 at 23:43
  • 1
    Binary read/write is far more complicated than this. We can't see what `Player` looks like either, but can get a pretty good guess (which really isn't good for this site) that you have dynamic members like `std::string ingame_name;`, etc. None of that will read/write raw as you're trying to do. You need to develop a formal binary format and a protocol for reading/writing. @CaptainGiraffe 's answer suggesting you use a multi-line text file is good, as it solves most of those problems. Chances are you don't need fixed-record-length semantics, so I'd do that. – WhozCraig May 19 '20 at 23:51
  • In general, you don't use `operator>>` or `operator<<` when performing binary I/O. Search your favorite C++ reference for `std::istream::read()` and `std::ostream::write()`. You'll also want to open the file in binary mode (to eliminate any funky translations). – Thomas Matthews May 19 '20 at 23:51
  • Well thanks guys i guess i ll rewrite everything in text file instead :') – Yassine Mrabet May 19 '20 at 23:53
  • IMHO, you want to keep your data in a human readable format. This will make debugging and testing a whole lot easier. When writing in binary, you'll need a hex-editor or editor that can show binary data, to verify that the data is written and read correctly. Big pain. I recommend XML, as there are existing libraries and it is human readable. – Thomas Matthews May 19 '20 at 23:54

2 Answers2

1

The question isn't much specific as for what doesn't work, however, for keeping track of the ID I suggest using a static variable at the top of the function like this:

static int playerid = 0;

The static keyword means that it will only set the variable to zero once, and it will not delete the data after the end of the function. Which means you just save the 'playerid' into the file, then increase it by 1. The next time the function will be called, playerid will be larger by 1.

Edit: while (!file.eof()) doesn't work because you're using ios::app, it already starts at file.eof(), so the loop shouldn't do anything.

Michael Haephrati
  • 3,660
  • 1
  • 33
  • 56
enzeys
  • 108
  • 9
  • Well it doesn't matter if the data will be deleted. It can be set to 0 every time the function is called and after that it will be increased after calculating the number of objects in file, right ? – Yassine Mrabet May 19 '20 at 23:34
  • That is true, but I find my way more convenient as there is no need to count the number of objects inside the file. – enzeys May 19 '20 at 23:37
  • This does not provide an answer to the question. Once you have sufficient [reputation](https://stackoverflow.com/help/whats-reputation) you will be able to [comment on any post](https://stackoverflow.com/help/privileges/comment); instead, [provide answers that don't require clarification from the asker](https://meta.stackexchange.com/questions/214173/why-do-i-need-50-reputation-to-comment-what-can-i-do-instead). - [From Review](/review/low-quality-posts/26175010) – Michael Haephrati May 20 '20 at 12:15
  • @MichaelHaephrati I believe my answer follows the guides in the link you posted. If you read the original question you'll see it's asking about saving the player id, and I believe I answered that. – enzeys May 20 '20 at 14:23
  • @enzays, "Please be more specific in what doesn't work" looks more like a comment or part of a discussion. Can you edit your answer then? – Michael Haephrati May 20 '20 at 19:05
  • @MichaelHaephrati From the link you posted: "Answers don't have to be exhaustive or infallible, they just need to try to answer the question. It's perfectly fine to post an answer saying, for example, "I'm not sure what the cause of your problem is, but if it's X, you can solve it by doing Y. If that doesn't help, try Z and let me know what it says."" – enzeys May 20 '20 at 20:26
1

I'd recommend storing the players in a text file that you parse instead of storing them as binary data. This has a lot of advantages.

The biggest difficulty with your approach is that you need to design a binary format for your player object. Something like

id+N1+'fullname'+N2+'email'+N3+'ingame-name'
4 bytes id, N1 number of characters in fullname(4 bytes),
the characters in fullname as indicated by N1
same for N2 + email and so on.

This requires fairly complicated logic for reading and writing a player.

On the other hand you could have a text file looking like

1
Yassin Mrabet
20
player@gamers.net
playerino1336
2
Captain Giraffe
55
player1@gamers.net
playerino1337

This is a lot easier to write code for. A new player every fifth getline.

A sample readPlayer member could look like (should probably be static, not super important right now)

Plkayer Player::readPlayer(istream& in){
    std::string str_id;
    std::getline(in, str_id);
    std::string fullname;
    std::getline(in, fullname);
    std::string str_age;
    std::getline(in, str_age);
    std::string email;
    std::getline(in, email);
    std::string player_name;
    std::getline(in, player_name);
    int age = std::stoi(str_age);
    int id = std::stoi(str_id);
    if(!in)  // read was unsuccessful.
        handle_bad_read();
    return Player(id, fullname, age, email, player_name);
}

The return statement of course requires a constructor that accepts exactly those arguments, but that constructor will be useful in many other situations too.

Captain Giraffe
  • 14,407
  • 6
  • 39
  • 67
  • The problem is i have many other function already implemented in my project and works fine with binary file ( like delete / modify ... ). So destroy everything and recreate because of that function :'( ? – Yassine Mrabet May 19 '20 at 23:46
  • Biggest advantage besides ease of coding: platform independence. Unless you're coding for an EBCDIC platform or some other nuance, the text-file approach will work literally everywhere. – WhozCraig May 19 '20 at 23:47
  • @YassineMrabet I understand your reluctance, but yes, I would absolutely recommend this approach. – Captain Giraffe May 19 '20 at 23:50
  • XML may be a good format to store the data, as it is readable and there are libraries for reading and writing in XML format. – Thomas Matthews May 19 '20 at 23:52
  • @ThomasMatthews Sure if he would require a perceived type-safety over heterogenous systems, sure. I'm more of a plain text guy myself. – Captain Giraffe May 19 '20 at 23:54
  • @YassineMrabet If this answer was useful for your question it is a good idea to accept it. – Captain Giraffe May 20 '20 at 01:56