1
resposta

Problema com a adição de palavras no arquivo

Quando adicionava uma nova palavra ao arquivo eram puxadas várias palavras repetidas e por isso precisei liberar o arquivo com a função free.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <locale.h>
#include "Forca.h"

char palavrasecreta[20]; //Palavra a ser descoberta
char chutes[26]; //É possível chutar todas as letras do alfabeto
int chutesdados = 0; //O usuário inicia o jogo sem ter dado nenhum chute

int perdeu(){
    int erros = 0; /*Variável de controle de quantas vezes o usuário errou*/
    
    for(int i=0; i < chutesdados; i++){ 
        
        int existe=0; /*Variável booleana que informa se a letra que foi chutada pertence ou não à palavrasecreta*/
        for(int j=0; j<strlen(palavrasecreta) ;j++){ 
            
            if(chutes[i]==palavrasecreta[j]){ /*Compara a letra na posição i do array 'chutes' com a letra na posição j do vetor 'palavrasecreta'*/
                existe=1;
                break; /*Se foi um chute correto o laço de repetição finaliza*/
            }
        }
        if(!existe){ erros++;} 
    }
    return erros>=1;
}


int ganhou(){ 
    for (int i = 0; i<strlen(palavrasecreta); i++){ /*Varrendo letra a letra da palavrasecreta*/
        /*Se o usuário ainda não chutou a letra que está na posição i da palavrasecreta, então ele ainda não ganhou*/
        if(!jachutou(palavrasecreta[i])){
            return 0;
        }
    }
    return 1;
}

void cabecalho(){
    printf("*****************************************\n");
    printf("*******       Jogo de Forca        ******\n");
    printf("*****************************************\n\n");
}

void novochute(){
    char chute;
    printf("\nChute: ");
    scanf(" %c",&chute); /*Espaço antes do %c para que seja ignorado o enter que damos ao chutar*/  
    //Os chutes são armazenados no vetor 'chutes'===========================================================================
    chutes[chutesdados]=chute; 
    chutesdados++;
}

int jachutou(char letra) {
    
    int achou=0;
    for (int j=0; j<chutesdados; j++){ /*Varrendo o vetor de chutes - A letra já foi chutada ?*/
         if (chutes[j]==letra){
         	achou=1;
            break;
         }
     } 
     return achou;
}

void desenhaforca(){
    
    printf("\n");
    printf("Você já deu %d chutes\n", chutesdados);
    for (int i=0; i<strlen(palavrasecreta); i++){ /*=======Varrendo o vetor de palavrasecreta - Imprime a palavra secreta*/
        
         if(jachutou(palavrasecreta[i])){
         	
             printf("%c",palavrasecreta[i]);
         }
         else {
         printf("_ ");
         }
     }
     printf("\n");
}

void escolherpalavra(){
    FILE* f;
    
    f=fopen("palavras.txt", "r"); /*Devolve um ponteiro de arquivo*/
    
    if(f==0){
        printf("Desculpe, banco de dados de palavras nao disponivel\n\n");
        exit(1);
    }
    
    //Descobrindo a quantidade de palavras do arquivo
    int qtddepalavras; /*Definimos que a primeira linha do arquivo conterá a quantidade de palavras*/
    fscanf(f,"%d",&qtddepalavras);/*O ponteiro qtddepalavras recebe o valor inteiro da leitura de f*/
    
    //Mesma técnica de escolha de um número randômico vista anteriormente
    srand(time(0)); /*Escolher uma linha aleatória do arquivo*/
    int randomico=rand()%qtddepalavras; 
    
    //A leitura ocorre de forma sequencial por conta do ponteiro
    for(int i=0; i<=randomico ;i++){
        fscanf(f,"%s",palavrasecreta); /*Lê uma string qualquer do arquivo f e armazena na palavrasecreta - Como já tinha lido a primeira linha, aqui já começa a partir da segunda*/
    }
    fclose(f);
}

void adicionapalavra(){
    char quer;
    
    printf("Gostaria de adicionar uma nova palavra? (S/N)");
    scanf(" %c",&quer);
    
    if(quer== 'S'){
        
        char novapalavra[20];
        
        printf("Qual a nova palavra (escreva em letras maiusculas)? ");
        scanf("%s",novapalavra);
        
        FILE* f;
        
        f = fopen("palavras.txt","r+"); //Abrindo o arquivo com permissões de leitura e escrita
        if(f==0){
            printf("Banco de dados de palavras não disponível\n\n");
            exit(1);
        }
        
        //Descobrindo a quantidade de palavras que estão no arquivo
        int qtd;
        fscanf(f,"%d",&qtd);
        qtd++;
        
        //Apontando o file (ponteiro) pro começo do arquivo
        fseek(f,0,SEEK_SET);
        fprintf(f,"%d",qtd);
        
        //Apontando o file (ponteiro) pro final do arquivo
        fseek(f,0,SEEK_END);
        fprintf(f,"\n%s",novapalavra);
        
        fclose(f);
        free (novapalavra);
    }
}

int main (){
    setlocale(LC_ALL, "Portuguese");
//Chama a função 'cabecalho'===============================================================================================
     cabecalho();
//Chama a função escolher a 'palavrasecreta'===============================================================================
     escolherpalavra();
//Repete até ganhar ou perder==============================================================================================
     do{
         
        desenhaforca();
        novochute();
        
     } while (!ganhou() && !perdeu());
     
     adicionapalavra();
}
1 resposta

Olá Lorena.

Tudo bem?

Você mencionou que usou a função free para liberar o arquivo, mas essa função é usada para liberar memória alocada dinamicamente, não para arquivos.

Vamos tentar fazer algumas mudanças:

  1. Remover o uso de free em adicionapalavra: free não deve ser usado para liberar memória de variáveis locais (como novapalavra), e muito menos para arquivos.

  2. Tente corrigir a leitura e escrita no arquivo: Certifique-se de que o arquivo está sendo manipulado corretamente. Você não precisa liberar a memória de novapalavra, pois ela é uma variável local e será liberada automaticamente quando a função terminar.

Aqui está a versão ajustada da função adicionapalavra:

void adicionapalavra(){
    char quer;
    
    printf("Gostaria de adicionar uma nova palavra? (S/N) ");
    scanf(" %c", &quer);
    
    if(quer == 'S'){
        
        char novapalavra[20];
        
        printf("Qual a nova palavra (escreva em letras maiusculas)? ");
        scanf("%s", novapalavra);
        
        FILE* f;
        
        f = fopen("palavras.txt", "r+"); // Abrindo o arquivo com permissões de leitura e escrita
        if(f == 0){
            printf("Banco de dados de palavras não disponível\n\n");
            exit(1);
        }
        
        // Descobrindo a quantidade de palavras que estão no arquivo
        int qtd;
        fscanf(f, "%d", &qtd);
        qtd++;
        
        // Apontando o file (ponteiro) pro começo do arquivo
        fseek(f, 0, SEEK_SET);
        fprintf(f, "%d", qtd);
        
        // Apontando o file (ponteiro) pro final do arquivo
        fseek(f, 0, SEEK_END);
        fprintf(f, "\n%s", novapalavra);
        
        fclose(f);
    }
}

Além disso, certifique-se de que o arquivo palavras.txt está no mesmo diretório que o seu executável e que ele está no formato correto, com a primeira linha indicando o número de palavras e as palavras seguintes em linhas separadas.

Veja se faz sentido e faça as mudanças em seu código.

Espero ter ajudado. Qualquer dúvida manda aqui. Bons estudos.