1
resposta

Como ocorre a alteração no contador de palavras do arquivo txt

Não estou entendendo qual parte da função "salva_arquivo" altera o contador de palavras no arquivo .txt quando eu adiciono uma palavra nova.

Código:

#include <iostream>
#include <string>
#include <map>
#include <vector>
#include <fstream>
#include <ctime> // para inserir seed dos números aleatórios
#include <cstdlib> // para usar as funções random
using namespace std;

string palavra_secreta = "MELANCIA";
map<char, bool> chutou;
vector<char> chutes_errados;

bool letra_existe(char chute){
    /*for(int i = 0; i < palavra_secreta.size(); i++){
        if(chute == palavra_secreta[i]){
            return true;
        }
    }*/
    for(char letra : palavra_secreta){
        if(chute == letra){
            return true;
        }
    }
    return false;
}

bool nao_acertou() {
    for(char letra : palavra_secreta){
        if(!chutou[letra]){
            return true;
        }
    }
    return false;
}

bool nao_enforcou(){
    return chutes_errados.size() < 5;
}

void imprime_cabecalho(){
    cout << "*********************" << endl;
    cout << "*** Jogo da Forca ***" << endl;
    cout << "*********************" << endl;
    cout << endl;
}

void imprime_erros(){
    cout << "Chutes errados: ";
    for(char letra: chutes_errados){
        cout << letra << " ";
    }
    cout << endl;
}

void imprime_palavra(){
  for(char letra : palavra_secreta){
        if(chutou[letra]){
            cout << letra << " ";
        }
        else{
            cout << "_ ";
        }
    }
    cout << endl;  
}

void chuta(){
    char chute;
    cout << "Seu chute: ";
    cin >> chute;

    chutou[chute] = true;

    if(letra_existe(chute)){
        cout << "Voce acertou! Seu chute esta na palavra." << endl;
    }
    else{
        cout << "Voce errou! Seu chute nao esta na palavra." << endl;
        chutes_errados.push_back(chute); //joga o valor(char) errado no final do vetor
    }
    cout << endl;
}

vector<string> le_arquivo(){ // função que retorna as palavras no arquivo p/ um vector
    ifstream arquivo; // Input File Stream -> lê outros arquivos
    arquivo.open("palavras.txt");

    if(arquivo.is_open()){ // boa prática
        int quantidade_palavras;
        arquivo >> quantidade_palavras;

        vector<string> palavras_do_arquivo;

        for(int i=0; i<quantidade_palavras; i++){
            string palavra_lida;
            arquivo >> palavra_lida;
            palavras_do_arquivo.push_back(palavra_lida);
        }

        arquivo.close(); // boa prática
        return palavras_do_arquivo;
    }
    else{
        cout << "Nao foi possivel acessar o banco de palavras."<< endl;
        exit(0);
    }
}

sorteia_palavra(){
    vector<string> palavras = le_arquivo();

    srand(time(NULL));
    int indice_sorteado = rand() % palavras.size();

    palavra_secreta = palavras[indice_sorteado];
}

void salva_arquivo(vector<string> nova_lista){
    ofstream arquivo; //output file stream -> escreve valores no arquivo
    arquivo.open("palavras.txt");
    if(arquivo.is_open()){
       arquivo << nova_lista.size() << endl;

       for(string palavra : nova_lista){
           arquivo << palavra << endl;
       }
        arquivo.close();
    }
    else{
        cout << "Nao foi possivel acessar o banco de palavras."<< endl;
        exit(0);
    }
}

void adiciona_palavra(){
    cout << "Digite a nova palavra, usando letras maiusculas." << endl;
    string nova_palavra;
    cin >> nova_palavra;

    vector<string> lista_palavras = le_arquivo();
    lista_palavras.push_back(nova_palavra);

    salva_arquivo(lista_palavras);
}

int main () {  
    imprime_cabecalho();

    le_arquivo();
    sorteia_palavra();

    while(nao_acertou() && nao_enforcou()){
        imprime_erros();

        imprime_palavra();

        chuta();     
    }

    cout << "Fim de jogo!" << endl;
    cout << "A palavra secreta era: " << palavra_secreta << endl;
    if(nao_acertou()){
        cout << "Voce perdeu! Tente novamente!" << endl;
    }
    else{
        cout << "Parabens! Voce acertou a palavra secreta!" << endl;

        cout << "Voce deseja aicionar uma nova palavra ao banco? (S/N) ";
        char resposta;
        cin >> resposta;
        if(resposta == 'S'){
            adiciona_palavra();
        }
    }
}




arquivo.txt:

6
ABACAXI
BANANA
UVA
MELANCIA
MORANGO
LARANJA
1 resposta

Quando você chama a função no seu código, você passa a nova lista de palavras que irá ser salva no arquivo, sobreescrevendo este mesmo arquivo.

Antes de comentar linha a linha da função salva_arquivo ou explicar o fluxo de novo de como pegamos as palavras e adicionamos as palavras, tudo bem?

Vamos lá, ao abrir e ler o arquivo, a primeira linha o programa identifica a quantidade de palavras através do trecho:

arquivo >> quantidade_palavras;

Com isso ele faz a validação necessária, então ele continua lendo linha a linha e preenchendo o vetor de strings, vector, com cada palavra, que é em seguida retornado ao final da execução.

Quando queremos adicionar uma nova palavra, nós pegamos o vetor antigo, adicionamos a nova palavra ao final dele através do comando push_back e então passamos esse vetor como o parametro nova_lista da função salva_arquivo. E agora irei comentar linha a linha do código:

// Passamos aqui o vetor com a palavra adicionada como parametro.

void salva_arquivo(vector<string> nova_lista){
    ofstream arquivo; //output file stream -> escreve valores no arquivo
    arquivo.open("palavras.txt"); // aqui abrimos o arquivo "palavras.txt"
    if(arquivo.is_open()){ // aqui verificamos se o arquivo está aberto 
       arquivo << nova_lista.size() << endl; // aqui já começamos a escreve na primeira linha do arquivo, e como pode ver estamos escrevendo aqui o tamanho da lista através da função .size() que é disponível no tipo vector<>, este tamanho da lista é justamente a quantidade de palavras

       for(string palavra : nova_lista){ // esse laço for inicia para passar de palavra em palavra que está dentro do vetor
           arquivo << palavra << endl; // e aqui estamos escrevendo cada palavra em uma nova linha do arquivo
       }
        arquivo.close(); // aqui fechamos o arquivo
    }
    else{
        cout << "Nao foi possivel acessar o banco de palavras."<< endl;
        exit(0);
    }
}

Lembrando que essa operação sobreescreve o arquivo anterior, mas parece que apenas adicionamos a palavra ao final e modificamos a quantidade de palavras na primeira.