srstafion
srstafion

Reputation: 11

Overwrite the first line, add new ones after it in the file

I want to make a score system in my game that will save the individual score (int score) of every player (string input) as well as the sum of every player score (scoreTotal). To do that I want to keep the scoreTotal in the first line of the file and overwrite it every time the function is called, and then after it, create a new line for each player and his score, how do I do that?

Here is my code (not working):

void saveScore(int scoreTotal, int score, string input) {
    scoreTotal += score;
    ofstream total("score.txt");
    if (total.is_open()) {
        total << scoreTotal;
    }
    total.close();

    ofstream scoreFile("score.txt", ios::app);
    if (scoreFile.is_open()) {
        scoreFile << endl << input << " : " << score;
    }
    scoreFile.close();
}

(after inputting 3 players I get the totalScore correctly but there is only the third player on the second line)

Upvotes: -1

Views: 58

Answers (3)

Uli
Uli

Reputation: 31

I wrote a code that does what you need, you just need to change the parameters on saveScore, if there is no text document created before, system creates a new one, when there is already a text document created, system adds the new score to the total score on the first line and also append the new score record to the list with all the players.

#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

void saveScore(int, string);

int main() {

   saveScore(10, "Player 1");

   return 0;
}

void saveScore(int score, string input) {

int scoreTotal;

   ifstream scoreFile("score.txt");
   if (scoreFile.is_open()) {
      string line;
      getline(scoreFile, line);
      string numText;

      for(int i=13 ; i<line.size(); i++){
         numText += line[i];
      }
      scoreTotal = stoi(numText) + score;

      vector<string> lines;
      while (getline(scoreFile, line)) {
         lines.push_back(line);
      }

      scoreFile.close();

      ofstream scoreFile("score.txt");
      if (scoreFile.is_open()) {
         scoreFile<<"Total score: "<<scoreTotal<<endl;
         for (string line : lines) {
         scoreFile << line << endl;
         }
         scoreFile<<input<<": "<<score;
         scoreFile.close();
      }
      else{
         scoreFile.close();
      }
   }
   else{
      cout<<"Archivo creado";
      ofstream scoreFile("score.txt");
      scoreFile<<"Total score: "<<score<<endl;
      scoreFile<<input<<": "<<score;
      scoreFile.close();
   }
   
}

Good luck, my friend :)

Upvotes: 0

Remy Lebeau
Remy Lebeau

Reputation: 597916

What you are attempting to do can succeed only if the new score has the same number of digits and formatting as the previous score.

Otherwise, if the new score has fewer digits, the new line would be shorter than the existing line, leaving behind artifacts of the old data.

Likewise, if the new score has more digits, then the new line will be longer than the existing line and overwrite a portion of the following line.

To do what you want, you should read in the original file in full, then modify the data as needed, and then completely write out a new file in full.

Otherwise, don't use a text format for your file. Use a binary format instead, then the score will not change byte size regardless of its value, so you can simply seek to and overwrite just those bytes of the score without affecting the rest of the file.

Upvotes: 0

Skerdi Velo
Skerdi Velo

Reputation: 368

the problem here is that you override every time the file. To fix your bug, you need to read first all the data inside the file, and then you can modify the score. Here is a simple code:

void saveScore(int scoreTotal, int score, string input) {
    vector<string> scores;
    string line;
    ifstream scoreFileRead("score.txt");
    if (scoreFileRead.is_open()) {
        getline(scoreFileRead, line); //Skip the total score line
        while (getline(scoreFileRead, line)) {
            scores.push_back(line);
        }
        scoreFileRead.close();
    }

    scoreTotal += score;
    ofstream scoreFileWrite("score.txt");
    if (scoreFileWrite.is_open()) {
        scoreFileWrite << scoreTotal << endl;
        for (const string& scoreLine : scores) {
            scoreFileWrite << scoreLine << endl;
        }
        scoreFileWrite << input << " : " << score;
        scoreFileWrite.close();
    }
}

So this should fix your problem.

Upvotes: 0

Related Questions