0

La idea es que al morir el usuario ingresa su nombre y este se guarda junto con su puntaje manteniendo los nombre y puntajes que ya estaban guardados. el problema es que el codigo que tengo solamente sobreescribe el archivo anterior y guarda el ultimo nombre ingresado. Probe abriendo el fichero y asando todos los datos dentro de este a un string auxiliar pero la unica forma de leer datos de un fichero de texto que conozco es .getline() y esta funcion utiliza char en vez de string

este es el codigo:

al morir el jugador se ingresa el nombre.

    if (aircraft.isDead(false)){
        bool flag = false;

        text.setString("Juego Terminado \n Ingresa tu nombre:");
        text.setPosition(200, 200);

        if (event.type == sf::Event::TextEntered){
            if (event.text.unicode < 128 && event.text.unicode != 13){
                name.push_back(static_cast<char>(event.text.unicode));
                playerName.setPosition(200, 300);
                playerName.setString(name);
            }
            if (event.text.unicode == 13){
                Save(name);

            }
        }
    }

la funcion Save:

void Game::Save(std::string nombre){
std::ofstream archivo("Puntajes.txt");

if (archivo.is_open()){
    aircraft.saveScore(archivo, nombre);
}
archivo.close();
}

la funcion saveScore de la clase aircraft:

void Aircraft::saveScore(std::ofstream &archivo, std::string nombre){
archivo << '\n'+nombre+": "+scorestr;
}

1 Answers1

1

Problema.

Tienes que abrir el archivo en modo de agregar datos. El modo de apertura de archivo por defecto es sobre-escritura.

No tendrías este problema si hubieras leído la documentación disponible sobre la utilidad std::ofstream, así que la solución sería...

Solución.

Lee la documentación disponible sobre la utilidad std::ofstream.

Descripción del problema, paso a paso.

La clase std::ofstream es una abstracción de flujo de salida de datos de la familia std::ostream (igual que std::cout)

Constructor.

std::ofstream se especializada en enviar datos a archivo, dispone de 7 constructores (uno de ellos borrado y tres de ellos dependientes de std::filesystem de C++17) pero sólo uno de ellos es relevante para esta pregunta:

  • explicit basic_ofstream( const char* filename, std::ios_base::openmode mode = ios_base::out );

    Crea un flujo de salida de datos a archivo apuntando al archivo identificado por el primer parámetro, si no se especifica nada el segundo parámetro obtiene el valor std::ios_base_out.

Modos de apertura.

El segundo parámetro del constructor que estás usando especifica los modos de apertura del archivo, es un parámetro de tipo std::ios_base::openmode. Hay seis modos de apertura disponibles pero sólo uno de ellos es adecuado a tus necesidades:

  • std::ios_base::app Significa añadir (append). Tras abrir el archivo sitúa el puntero de escritura al final del mismo.

Propuesta.

Cambia tu función Game::Save de la siguiente manera:

void Game::Save(std::string nombre){
    if (std::ofstream archivo{"Puntajes.txt", std::ios_base::app}){
        aircraft.saveScore(archivo, nombre);
    }
}

Más detalles de cómo funciona el código anterior en esta pregunta.

PaperBirdMaster
  • 44,474
  • 6
  • 44
  • 82