Partage
  • Partager sur Facebook
  • Partager sur Twitter

Chargement de partie crashe...

Sousprog, fichiers

    8 janvier 2022 à 23:07:00

    Bonsoir à tous,

    Actuellement travaillant sur une possibilité de sauvegarder et de charger dans mon jeu, j'ai un problème qui est tout bête mais je ne comprends pas vraiment ce que le programme essaye de me dire (et quand je lance ça crashe)  : 

    Une suggestion ?

    #include // Les bibliothèques... //
    
    void chargerpartie1(int nb_joueurs, t_joueur joueur_x[], t_carte cartes) // Sauvegarde n°1
    {
        FILE* sauvegarde1 = NULL;
        sauvegarde1 = fopen("sauvegarde1.txt", "r"); // "r" pour LECTURE donc on voit SI IL YA UN FICHIER
        if (sauvegarde1 == NULL)
        {
            printf("\nIl n'y a pas de fichier de sauvegarde.");
        }
    
        if (sauvegarde1 != NULL)
        {
            fscanf(sauvegarde1, "%d", &nb_joueurs);
            for (int x = 0; x < nb_joueurs; x++) // Boucle pour lire les structures
            {
                fgets(sauvegarde1, "%s", joueur_x[x].pseudo);
                fscanf(sauvegarde1, "%d", &joueur_x[x].argent);
                fscanf(sauvegarde1, "%d", &joueur_x[x].position);
                fscanf(sauvegarde1, "%d", &joueur_x[x].ancienne_position);
                fscanf(sauvegarde1, "%d", &joueur_x[x].prison);
            }
            fclose(sauvegarde1);
            sauvegarde1 = NULL;
        }
        // partiealternative(nb_joueurs, joueur_x);
    }
    



    • Partager sur Facebook
    • Partager sur Twitter
      8 janvier 2022 à 23:17:25

      Hello,

      fgets() ne s'emploie pas comme fscanf() ! Manuel fgets() (en anglais)

      Attention aussi au fait que le \n sera inclus dans la variable lue (c'est indiqué dans le lien, mais j'attire quand même ton attention sur ce fait). Mais il y a un moyen simple pour s'en débarraser :-)

      -
      Edité par edgarjacobs 8 janvier 2022 à 23:24:44

      • Partager sur Facebook
      • Partager sur Twitter

      Il y a ceux qui font des sauvegardes, et ceux qui n'ont pas encore eu d'incident....

        8 janvier 2022 à 23:42:13

        Autant utiliser 'fscanf' à la place de 'fgets', non ? C'est parce que le pseudo peut contenir des blancs ? Dans ce cas il est possible d'adapter le format.
        • Partager sur Facebook
        • Partager sur Twitter
          8 janvier 2022 à 23:58:41

          Ok, maintenant ça fonctionne, mais j'ai l'impression que le scan des variables se fait mal... 

          Mes fprintf (quand je sauvegarde) font "%(type)\n" sur le fichier texte.

          Est ce que le fscanf "%d" ou meme le fgets detecte automatiquement la variable à scanner ? 

          Je ne sais pas si c'est clair mais... J'espère que vous avez compris

          Affichage après une charge de partie : 

          Affichage normal voulu : 

          -
          Edité par Clément 2910 9 janvier 2022 à 0:07:02

          • Partager sur Facebook
          • Partager sur Twitter
            9 janvier 2022 à 0:30:52

            Peux-tu montrer la fonction qui sauvergarde la partie et celle (dernière mouture) qui la charge, ainsi que le fichier sauvegardé (comme si tu postais du code) et la structure t_joueur ?

            -
            Edité par edgarjacobs 9 janvier 2022 à 0:31:45

            • Partager sur Facebook
            • Partager sur Twitter

            Il y a ceux qui font des sauvegardes, et ceux qui n'ont pas encore eu d'incident....

              9 janvier 2022 à 0:41:28

              Charge : 

              #include "../Structures/structure_joueur.h"
              
              void chargerpartie1(int nb_joueurs, t_joueur joueur_x[], t_carte cartes) // Sauvegarde n°1
              {
                  FILE* sauvegarde1 = NULL;
                  sauvegarde1 = fopen("sauvegarde1.txt", "r"); // "r" pour LECTURE donc on voit SI IL YA UN FICHIER
                  if (sauvegarde1 == NULL)
                  {
                      printf("Il n'y a pas de fichier de sauvegarde.");
                  }
              
                  if (sauvegarde1 != NULL)
                  {
                      fscanf(sauvegarde1, "%d", &nb_joueurs);
                      for (int x = 0; x < nb_joueurs; x++) // Boucle pour lire les structures
                      {
                          fgets(joueur_x[x].pseudo, 20, sauvegarde1);
                          fscanf(sauvegarde1, "%d", &joueur_x[x].argent);
                          fscanf(sauvegarde1, "%d", &joueur_x[x].position);
                          fscanf(sauvegarde1, "%d", &joueur_x[x].ancienne_position);
                          fscanf(sauvegarde1, "%d", &joueur_x[x].prison);
                      }
                      fclose(sauvegarde1);
                      sauvegarde1 = NULL;
                  }
              }
              
              
              

              Sauvegarde : 

              void sauvegardeclassique(int nb_joueurs, t_joueur joueur_x[], t_carte cartes) // Sauvegarde n°1
              {
                  FILE* sauvegarde1 = NULL;
                  sauvegarde1 = fopen("sauvegarde1.txt", "w"); // "w" pour ECRASEMENT donc on crée un NOUVEAU FICHIER et on ECRASE l'autre si il y'en a un
              
                  fprintf(sauvegarde1, "%d\n", nb_joueurs);
                  for (int x = 0; x < nb_joueurs; x++) // Boucle pour sauvegarder les structures
                  {
                      fflush(stdin);
                      fprintf(sauvegarde1, "%s\n", joueur_x[x].pseudo);
                      fprintf(sauvegarde1, "%d\n", joueur_x[x].argent);
                      fprintf(sauvegarde1, "%d\n", joueur_x[x].position);
                      fprintf(sauvegarde1, "%d\n", joueur_x[x].ancienne_position);
                      fprintf(sauvegarde1, "%d\n", joueur_x[x].prison);
                  }
                  fclose(sauvegarde1);
                  sauvegarde1 = NULL;
              
              
              }

              Fichier de sauvegarde1 (txt) (Pour 2 joueurs du coup) :

              2

              bart

              1404

              6

              3

              0

              marge

              1496

              3

              0

              0

              Structure joueur :

              typedef struct players
              {
                  char pseudo[20];
                  int argent;
                  int position;
                  int ancienne_position;
                  bool prison;
              
              }t_joueur;
              





              -
              Edité par Clément 2910 9 janvier 2022 à 0:43:27

              • Partager sur Facebook
              • Partager sur Twitter
                9 janvier 2022 à 0:52:00

                Et si tu ajoutes

                char *p;
                p=strchr(joueur_x[x].pseudo,'\n');
                if(p)
                    *p=0;

                après le fgets() pour supprimer le \n en fin du pseudo ?

                Et on ne fflush() pas stdin, ça peut amener à un comportement indéterminé. (en plus, tu n'as aucune raison de le faire à cet endroit-là puisque ut écris, tu ne lis pas).

                Il y a encore autre chose: la variable nb_joueur est locale à la fonction charger, et donc sa valeur ne sera jamais transmise à l'appelant. Soit tu passes un pointeur, soit ta fonction renvoie le nombre de joueurs.

                Edit: dans ta fonction de chargement, ajoute un espace après le %d dans les fscanf(): "%d_" ( _ = espace), ça et le petit bout de code que je t'ai donné résoudront ton problème.

                Code complet de test:

                #include <stdio.h>
                #include <string.h>
                #include <stdbool.h>
                
                typedef struct players
                {
                    char pseudo[20];
                    int argent;
                    int position;
                    int ancienne_position;
                    bool prison;
                 
                }t_joueur;
                
                
                void chargerpartie1(int *nb_joueurs, t_joueur joueur_x[]) // Sauvegarde n°1
                {
                    FILE* sauvegarde1 = NULL;
                    sauvegarde1 = fopen("sauvegarde1.txt", "r"); // "r" pour LECTURE donc on voit SI IL YA UN FICHIER
                    if (sauvegarde1 == NULL)
                    {
                        printf("Il n'y a pas de fichier de sauvegarde.");
                    }
                 
                    if (sauvegarde1 != NULL)
                    {
                        fscanf(sauvegarde1, "%d ", nb_joueurs);
                        for (int x = 0; x < *nb_joueurs; x++) // Boucle pour lire les structures
                        {
                            fgets(joueur_x[x].pseudo, 20, sauvegarde1);
                			char *p;
                			p=strchr(joueur_x[x].pseudo,'\n');
                			if(p)
                				*p=0;
                            fscanf(sauvegarde1, "%d ", &joueur_x[x].argent);
                            fscanf(sauvegarde1, "%d ", &joueur_x[x].position);
                            fscanf(sauvegarde1, "%d ", &joueur_x[x].ancienne_position);
                            fscanf(sauvegarde1, "%d ", &joueur_x[x].prison);
                        }
                        fclose(sauvegarde1);
                        sauvegarde1 = NULL;
                    }
                }
                
                void sauvegardeclassique(int nb_joueurs, t_joueur joueur_x[]) // Sauvegarde n°1
                {
                    FILE* sauvegarde1 = NULL;
                    sauvegarde1 = fopen("sauvegarde1.txt", "w"); // "w" pour ECRASEMENT donc on crée un NOUVEAU FICHIER et on ECRASE l'autre si il y'en a un
                 
                    fprintf(sauvegarde1, "%d\n", nb_joueurs);
                    for (int x = 0; x < nb_joueurs; x++) // Boucle pour sauvegarder les structures
                    {
                        fprintf(sauvegarde1, "%s\n", joueur_x[x].pseudo);
                        fprintf(sauvegarde1, "%d\n", joueur_x[x].argent);
                        fprintf(sauvegarde1, "%d\n", joueur_x[x].position);
                        fprintf(sauvegarde1, "%d\n", joueur_x[x].ancienne_position);
                        fprintf(sauvegarde1, "%d\n", joueur_x[x].prison);
                    }
                    fclose(sauvegarde1);
                    sauvegarde1 = NULL;
                 
                 
                }
                
                
                void Display(int n,t_joueur j[]) {
                	printf("%d joueurs\n",n);
                	for(int i=0;i<n;i++)
                		printf("%s %d %d %d %s\n",j[i].pseudo,j[i].argent,j[i].position,j[i].ancienne_position,j[i].prison ? "true": "false");
                }
                
                
                int main(void) {
                	int n=2;
                	t_joueur j[2]={
                		{"bart",1404,6,3,0},
                		{"marge",1496,4,3,0}
                	};
                	
                	Display(n,j);
                	sauvegardeclassique(n,j);
                	memset(j,0,sizeof(j));
                	Display(n,j);
                	chargerpartie1(&n,j);
                	Display(n,j);
                	
                	return(0);
                }


                Ce code me donne une warning, mais je ne sais pas s'il est possible de la régler

                j.c: In function 'chargerpartie1':
                j.c:38:35: warning: format '%d' expects argument of type 'int *', but argument 3 has type '_Bool *' [-Wformat=]
                             fscanf(sauvegarde1, "%d ", &joueur_x[x].prison);
                                                   ^
                

                -
                Edité par edgarjacobs 9 janvier 2022 à 1:40:30

                • Partager sur Facebook
                • Partager sur Twitter

                Il y a ceux qui font des sauvegardes, et ceux qui n'ont pas encore eu d'incident....

                  9 janvier 2022 à 13:00:06

                  Merci, ça fonctionne !

                  Néanmoins, pourquoi on doit mettre des espace sur les %(type) ?

                  • Partager sur Facebook
                  • Partager sur Twitter
                    10 janvier 2022 à 12:06:36

                    Bonjour,

                    Connais-tu les fonctions fwrite() et fread() ?

                    Elle pourraient te faciliter la vie pour sauver et charger tes structures ...

                    Bonne continuation.

                    • Partager sur Facebook
                    • Partager sur Twitter

                    Chargement de partie crashe...

                    × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                    • Editeur
                    • Markdown