segmentation fault

segmentation fault - C++ - Programmation

Marsh Posté le 10-02-2003 à 00:31:53    

bon voila pour résumer :  
 
le sujet :  
 
 
Spécification Externe :
 
Etant donné un fichier dont les lignes sont organisées comme suit :
- 1ere ligne : identite d'un joueur de foot
- 2eme ligne : identite du club de ce joueur
- 3eme ligne : identite d'un joueur de foot
- 4eme ligne : identite du club de ce joueur
Ecrire un programme qui prendra en paramètre le nom du fichier
contenant les joueurs et le nom du fichier résultat dans lequel on
mettra sur chaque ligne le joueur associé à son club.
 
 
Spécification Interne :
 
1/ Stratégie
 
 
--> on supposera que tous les joueurs ont un club et que chaque club à
    un joueur. cela veut donc dire qu'il y a un nombre pair de ligne
    et que chaque ligne contient un nom de joueur ou un club. (ce
    n'est pas au programme de gérer les erreurs dans le fichier de données)
 
nb_ligne : comptera le nombre de ligne lue et init à 0
 
la fonction main prendra en paramètre deux noms de fichiers (sur 10
caractère) qui seront le fichier de donnée (nom_donnees) et le fichier
resultat (nom_resultat).
ensuite :
 
les fonctions ci dessous ne se dérouleront que si argc = 3 sinon on ne
fait rien
 
ouverture du fichier nom_donnees en lecture seule. (fd)
ouverture du fichier nom_resultat en création. (fr)
 
si fd < 0 alors
  afficher le message ("erreur : fichier non existant. impossible de l'ouvrir" );
  retourne (-fd) et sortir du programme  
si fr < 0 alors
  afficher le message ("erreur : fichier déjà existant." );
  retourne (-fr) et sortir du programme  
sinon
  boucle
   lire la première ligne -> nom_joueur
   nb_ligne ++
   lire la seconde ligne -> nom_club  
   nb_ligne ++
   si nom_joueur & nom_club > 0 alors faire  
      concaténer nom_joueur + nom_club -> nom_joueur_club
      enregistrer nom_joueur_club  
   si nom_joueur & nom_club < 0 et (nb_ligne mod 2) = 0 alors faire
      sortir de la boucle et retourner 0
   si nom_joueur & nom_club < 0 et (nb_ligne mod 2) != 0 alors faire
      afficher un message d'erreur ("Structure du fichier non valide" )
      retourner (-nb_ligne);
      sortir de la boucle
   fin de si
  fin de boucle
fin de si
 
 
2/ Elements
 
nom_donnes : char [10] -> nom du fichier données
nom_resultat : char [10] -> nom du fichier résultat
fd, fr : variable entière initialisé à 0  
nom_joueur : char [30] -> variable pour la lecture du nom du joueur  
nom_club : char [30] -> variable pour la lecture du nom du club
nom_joueur_club : char [60] -> variable contenant le nom du joueur et
                               son club
nb_ligne : nombre de ligne depuis le début du fichier et initialisé à 0
 
 
 
 
le programme :
 
 

Code :
  1. /* POUR PLUS D'INFORMATION CONSULTER LE README */
  2. /* déclaration des bibliotèques */
  3. #include <stdio.h> // opérations d'entrées sorties
  4. #include <unistd.h> // opérations sur les fichiers
  5. #include <fcntl.h> // pour O_RDONLY
  6. #include <string.h> // pour strcat
  7. int main(int argc, char *argv[])
  8. {
  9.   /* Déclaration des variables */
  10.  
  11.   int fd = 0, fr = 0 ; // variable entière initialisé à 0  
  12.   char carlu [1] = ""; // caractère lu
  13.   char nom_joueur [30] ="" ; // variable pour la lecture du nom du joueur  
  14.   char nom_club [30] = ""; // variable pour la lecture du nom du club
  15.   char nom_joueur_club [60] ; // variable contenant le nom du joueur et son club
  16.   int nb_ligne = 0 ; // nombre de ligne depuis le début du fichier et initialisé à 0
  17.   int nb_joueur, nb_club ; // variable contenant la longueur de la chaine
  18.   /* vérifie si il y a 3 paramètre sinon on sort */
  19.   if (argc != 3) { printf("\nSyntaxe non valide. TP3 fichier_de_donnes fichier_resultat\n" ); return argc ; }
  20.   /* ouverture des fichiers */
  21.   fd = open (argv[1], O_RDONLY);
  22.   fr = open(argv[2], O_CREAT | O_RDWR, 0777);
  23.   /* verifie les fichier */
  24.   if (fd < 0) { printf("\nerreur : fichier non existant. impossible de l'ouvrir.\n" ) ; // fichier non existant
  25.                 return(-fd); // fin du programme
  26.               }
  27.   if (fr < 0) { printf("\nerreur : fichier déjà existant.\n" ) ; // fichier non existant
  28.                 return(-fr); // fin du programme
  29.               }
  30.   /* traiter le fichier */
  31.   do
  32.     {
  33.       /* lecture d'un joueur dans le fichier */
  34.       do
  35. {
  36.   nb_joueur = read(fd, carlu, 1);  // lecture caractère par caractère
  37.   strcat(nom_joueur, carlu);
  38. } while (carlu != "\n" ); // on sort à la fin de la ligne
  39.       nb_ligne ++ ;
  40.       /* lecture d'un club dans le fichier club */
  41.       do
  42. {
  43.   nb_club   = read(fd, carlu, 1);
  44.   strcat(nom_club  , carlu);
  45. } while (carlu != "\n" );
  46.       nb_ligne ++ ;
  47.       /* cas ou la structure du fichier n'est pas respecté on l'indique */
  48.       if ((nb_joueur > 0) & (nb_club > 0) & ((nb_ligne % 2)!=0)) { printf("\nStructure du fichier non valide\n" );
  49.                                                                    return(-nb_ligne); // fin du programme
  50.                                                                  }
  51.    
  52.       /* concatenation */
  53.       strcat(nom_joueur_club, nom_joueur) ;
  54.       strcat(nom_joueur_club, nom_club);
  55.       strcat(nom_joueur_club, "\n" );
  56.       /* ecriture dans le fichier resultat */
  57.       write(fr, nom_joueur_club, nb_joueur+nb_club);
  58.     } while ((nb_joueur > 0) & (nb_club > 0) & ((nb_ligne % 2)==0));
  59.   close(fr);
  60.   close(fd);
  61.   return(0); // retourne 0 si le programme c'est bien terminé
  62. }

 
 
 
et l'erreur :
quand je lance le prg avec par exemple :
TP3 donne resultat
avec donne contenant des valeurs il me retourne segmentation fault
 
et ensuite le problème (pendant un temps ça a marché...) c qu'il ne trouve pas le caractère de "\n" à la fin de chaque ligne lu.

Reply

Marsh Posté le 10-02-2003 à 00:31:53   

Reply

Marsh Posté le 10-02-2003 à 07:27:26    

Au lieu de balancer le sujet, le nom de ton prof, la couleur du slip de ta copine et autres, isole le bout de code qui foire, selon toi, et donne la trace (l'erreur, je veux dire le nom de l'erreur et sa description). Parce que là comme ça, ça donne pas envie de lire, même si ça a l'air simple a priori.


---------------
Le site de ma maman
Reply

Marsh Posté le 10-02-2003 à 08:36:50    

bah le bout de code qui foire c quand je lance le programme avec les paramètres.
si je mes en second paramètre (celui qui s'ouvre en lecture) un nom de fichier non valide, il me retourne bien mon message d'erreur, tandis que si je mes en second paramètre un nom de fichier valide il m'affiche segmentation fault dés le début du programme. si je mes un printf("ada" ); tout de suite après le { en dessous du main il me l'affiche même pas. :heink:  
pourtant j'ai vérifié j'ai bien les droits sur ce fichier.

Reply

Marsh Posté le 10-02-2003 à 12:42:19    

Je vois déjà un souci là :

Code :
  1. ...
  2. char carlu [1] = ""; // caractère lu  
  3. ...
  4.     do
  5.   nb_club   = read(fd, carlu, 1); 
  6.   strcat(nom_club  , carlu);
  7. } while (carlu != "\n" );
  8. ...


 
1. Tu définis carlu comme une chaîne de 1 caractère. Pas glop ça, une chaine de 1 caractère prend 2 octets (pas oublier le '\0' à la fin). Autant le read ne devrait pas trop râler (par contre attention, il ne devrait pas mettre le '\0' à la fin de la chaîne), autant le strcat derrière ne va pas être content du tout => joli jardinage mémoire en perspective, ce qui  pourrait expliquer le segfault.
2. On compare les chaînes de caractères avec un strcmp, pas avec un "!=" ou un "==". si tu veux comparer le caractère de ton carlu, soit tu passes par un strcmp, soit tu testes carlu[0] != '\n'
 
Petite question : pourquoi ne pas passer par les fopen, fread & cie pour ton fichier ?

Reply

Marsh Posté le 10-02-2003 à 13:28:17    

disons qu'on a pas encore vu le cours avec les fopen et compagnie. mais bon tant pis vais essayer avec fopen et fread.
petite question pratique : fread lit un fichier ligne par ligne ?

Reply

Marsh Posté le 10-02-2003 à 13:32:43    

LordAnkou a écrit :

si je mes un printf("ada" ); tout de suite après le { en dessous du main il me l'affiche même pas. :heink:  


 
 :pfff:  
 
le flux de sortie est bufferisé pour des raisons évidentes de perfs. mets printf("ada\n" ); plutot tu verras tout de suite mieux

Reply

Marsh Posté le 10-02-2003 à 13:32:47    

fread lit le nombre d'octet que tu lui file en parametre (no more, no less :D)

Reply

Marsh Posté le 11-02-2003 à 06:41:51    

lorill a écrit :

mets printf("ada\n" ); plutot tu verras tout de suite mieux

Ça ne garantit pas le flush, il faut le spécifier:

Code :
  1. printf("ada\n" ) ; fflush(stdout) ;


---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed