Eleminé les commentaire dont un fichier c ?

hafed22 Messages postés 9 Statut Membre -  
[Dal] Messages postés 6122 Date d'inscription   Statut Contributeur Dernière intervention   -
je cherche a eleminé les commentaire dont un fichier c , j'ai converti mon fichier en un tableau, ça marche mais le problème que lorsque j'exécute il ya un msg d'erreur le programme cesse de fonctionner

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define TAILLE_MAX 1000
typedef char tab[TAILLE_MAX][TAILLE_MAX];

void ELE_com(tab t ,int n)
{
char temp[TAILLE_MAX];
int i=0,j=0,lig_eff=0;
for(i=0;i<n;i++)
{
{for(j=0;j<strlen(t[i]);j++)
if (strcmp("/",t[i][j])==strcmp("*",t[i+1][j+1]))
{ strcpy(t[i],"");
lig_eff++; }}}
i=0; // indique les nombres des linges effacé
for(i=1;i<n;i++)
{ strcpy(t[i],temp);

strcpy(t[i],t[i+1]); /* éliminer les linges vides
strcpy(t[i+1],temp); }

return ;
}

10 réponses

  1. [Dal] Messages postés 6122 Date d'inscription   Statut Contributeur Dernière intervention   1 108
     
    Quelque chose comme cela devrait aller pour traiter les /* */ :

                        +------------------+
                        |commentaire = faux|
                        +------------------+
                                 +
                        +--------------------+
    +------------------>|Ligne = lire_ligne()|<----------------+
    |                   +--------------------+                 |
    |                            +                             |
    |                            v                             |
    |              oui  +---------------------+ non            |
    |            +-----+|commentaire == faux ?|+---+       non |
    |            |      +---------------------+    +           |
    |            |                                 v           |
    |            |        +---------------------------------+  |
    |            |        |Ligne contient au moins un "*/" ?|+-+
    |            |        +---------------------------------+
    |            |                            oui +
    |            |        +---------------------------------------------+
    |            |        |memmove de ce qui suit le premier "*/"       |
    |            |        |rencontré en écrasant Ligne à partir du début|
    |            |        +---------------------------------------------+
    |            |                                +
    |            |                        +------------------+
    |            |                        |commentaire = faux|
    |            v                        +------------------+
    |      non  +---------------------+           +
    | +--------+|Ligne contient "/*" ?|<-------------------+
    | |         +---------------------+                    |
    | |                  +                                 |
    | |                  |oui                              |
    | |                  v                                 |
    | |            +------------------------+              |
    | |        +--+|Ligne contient          |              |
    | |    non |   |aussi au moins un "*/" ?|              |
    | |        v   +------------------------+              |
    | |  +----------------+        + oui                   |
    | |  |Tronquer Ligne à|        v                       |
    | |  |partir de "/*"  |  +--------------------------+  |
    | |  +----------------+  |memmove de ce qui suit le |  |
    | |       +              |premier "*/" rencontré en |  |
    | | +------------------+ |écrasant Ligne à partir du|  |
    | | |commentaire = vrai| |"/*"                      |  |
    | | +------------------+ +--------------------------+  |
    | |       +                    +                       |
    | |   +------------+      +------------------+         |
    | +-->|Ecrire Ligne|      |commentaire = faux|+--------+
    |     +------------+      +------------------+
    |         +
    |         |
    +---------+

    Les commentaires /* */ doivent être traités en premier.

    "Ecrire Ligne" devrait, avant d'écrire la ligne, envoyer la Ligne à la fonction traitant les commentaires "//".

    L'algorithme ne traite pas le cas où "/*" ou "*/" se trouvent dans une chaîne de caractères.

    Dal
    1
  2. Heliotte Messages postés 1561 Statut Membre 92
     
    Bonsoir,
    Des accolades étaient mal placées, mais peut-être pas que ça .. a tester et nous dire si ça fonctionne ou non:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #define TAILLE_MAX 1000
    typedef char tab[TAILLE_MAX][TAILLE_MAX];
    
    
    void ELE_com(tab t ,int n)
    {
    	char temp[TAILLE_MAX];
    	int i=0,j=0,lig_eff=0;
    	for(i=0;i<n;i++)
    	{
    		for(j=0;j<strlen(t[i]);j++)
    		{	if (strcmp("/",t[i][j])==strcmp("*",t[i+1][j+1]))
    			{
    				strcpy(t[i],"");
    				lig_eff++;
    			}
    		}
    	}
    	i=0; // indique les nombres des linges effacé
    	for(i=1;i<n;i++)
    	{
    		strcpy(t[i],temp);
    		strcpy(t[i],t[i+1]); /* éliminer les linges vides */
    		strcpy(t[i+1],temp);
    	}
    	return ;
    }
    0
    1. hafed22 Messages postés 9 Statut Membre
       
      merci, mais çà reste le même problème "le programme cesse de fonctionner "
      0
  3. Char Snipeur Messages postés 10112 Date d'inscription   Statut Contributeur Dernière intervention   1 331
     
    Salut.
    Ce n'est pas très rigoureux tout ça.
    Dans ta boucle final, tu boucle jusqu'à "n" et met i+1, ce qui est incohérent, tu risque de dépasser la taille de ton tableau. Ensuite, tu copies temp qui n'est pas initialisé dans t[i] !

    if (strcmp("/",t[i][j])==strcmp("*",t[i+1][j+1])) Tu es sur que ça fonctionne comme tu veux ça ? et même problème de débordement de tableau
    0
  4. [Dal] Messages postés 6122 Date d'inscription   Statut Contributeur Dernière intervention   1 108
     
    Salut hafed22,

    Personnellement, je ne comprend pas ce que tu mets dans ton tableau de 1000x1000.

    Tu dois juste parcourir le fichier ligne par ligne et le traiter ligne par ligne (le stocker dans un tableau me parait inutile, sauf si tu veux faire d'autres choses qui le justifient), en déterminant un statut "je suis dans un commentaire" ou "je ne suis pas dans un commentaire", qui change suivant que tu rencontres "/*" et "*/", sachant que les commentaires peuvent courir sur plusieurs lignes.

    Pareil pour "//" dont l'effet sera cependant limité à une ligne à partir du signe.

    Et puis, si on veut bien faire, il faudrait aussi vérifier que ces marqueurs ne se trouvent pas dans une chaîne de caractères (peut-être il y a d'autres cas, il faut y réfléchir).

    Tu peux ouvrir ton fichier source en lecture d'un côté et ouvrir un fichier traité en écriture et y écrire ce que tu dois écrire.

    Dal
    0
  5. Vous n’avez pas trouvé la réponse que vous recherchez ?

    Posez votre question
  6. hafed22 Messages postés 9 Statut Membre
     
    merci pour vos réponse ,mais s.v.p est ce que vous pouvez corriger mon code !?
    0
    1. Char Snipeur Messages postés 10112 Date d'inscription   Statut Contributeur Dernière intervention   1 331
       
      je t'ai déjà indiqué des erreurs et comment les corrigées en partie. Met le code modifié, on verra après.
      0
  7. hafed22 Messages postés 9 Statut Membre
     
    s.v.p ça n'a pas marché !! ? :(
    0
    1. Char Snipeur Messages postés 10112 Date d'inscription   Statut Contributeur Dernière intervention   1 331
       
      développe
      0
  8. hafed22 Messages postés 9 Statut Membre
     
    Le problème reste comment supprimer ce commentaire " fputc( '\0',fichier);" il détecte le commentaire mais sans suppression

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #define TAILLE_MAX 1000
    typedef char tab[TAILLE_MAX][TAILLE_MAX];

    ELE_com(int n)
    {
    FILE* fichier=NULL;
    char buf[500];

    if((fichier = fopen("test.txt","r+"))==NULL)
    printf("\n ERREUR A L'OUVERTURE, CE FICHIER N'EXISTE PAS\n");
    else
    {
    while(NULL != fgets(buf, sizeof buf, fichier))
    {
    /* Une ligne a été lue */
    if(NULL != strstr(buf, "//"))
    {fputc('\0',fichier);

    printf("// found\n");

    fputc( '\0',fichier);

    }
    }

    }

    return 0 ;
    }
    0
  9. hafed22
     
    s.v.p me répondre !!
    0
    1. [Dal] Messages postés 6122 Date d'inscription   Statut Contributeur Dernière intervention   1 108
       
      Bonjour hafed,

      Si tu n'écris que des '\0' dans ton fichier, tu ne vas pas écrire grand chose (et il faut aussi ouvrir un fichier en écriture différent du fichier que tu lis).

      - écris les lignes qui ne contiennent pas de "//"
      - écris les lignes qui contiennent des "//" en les tronquant à partir de ce signe

      Pour ton strsrt sur "//", tu dois récupérer la valeur renvoyée, pour "supprimer" le contenu à partir du pointeur renvoyé, s'il n'est pas NULL (donc, en mettant '\0' à l'emplacement mémoire pointé par le résultat de strstr, puisque c'est comme cela que se terminent les chaînes de caractères en C).

      Ton code ne traite pas /* */.

      Mon message se contente de te redire des choses que j'ai déjà dites là https://forums.commentcamarche.net/forum/affich-26564394-elemine-les-commentaire-dont-un-fichier-c#4

      Tu n'as tenu aucun compte des recommandation faites par moi même ou d'autres, et ton code est très loin de faire ce que tu souhaites faire.

      C'est sans doutes une des raisons de l'absence de réponse. Nous n'allons pas écrire le code à ta place (ce n'est pas comme cela que fonctionne le forum de CCM).

      J'espère t'avoir donné des indications utiles, ou avoir clarifié des choses dites précédemment, si ce n'était pas clair.

      Essaye un peu mieux, s'il te plait :-)


      Dal
      0
  10. hafed22 Messages postés 9 Statut Membre
     
    La fonction "ELE_com" permit d'éliminer les commentaires d'un fichier c , les commentaires qui commencent par "//......... " ça marche ,mais le problème avec les commentaires par "/*................... */ "

    J'ai remarqué que :

    -les lignes après /* ne serons pas effacer...
    -Je pense que lorsque l'appel a fgets() pour la deuxième fois à l'intérieur de la boucle while le curseur sur INFILE (fichier) ne change pas pour fgets() de la première boucle while c'est-à-dire lorsque un commentaire effacée à l'intérieur de la boucle les lignes après /* et avant */ serons recopié de nouveau par la boucle principale !
    s.v.p votre aide !!
    Merci d'avance

    Mon code:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>

    /** fonction qui elemine les commentaires **/
    ELE_com()
    {FILE* INFILE,*OUTFILE;
    int l=0,i=0,j=0,pos=0;
    char buf[500],temp[500],c;

    OUTFILE=fopen("new.txt","w");
    if((INFILE = fopen("test.txt","r"))==NULL)
    printf("\n ERREUR A L'OUVERTURE, CE FICHIER N'EXISTE PAS\n");

    else
    {

    /* effacer les commentaires qui commence par // */
    while(NULL != fgets(buf, sizeof buf,INFILE))
    {if(NULL != strstr(buf, "//"))
    {
    while(buf[l]!='/')
    {l++;}
    for(i=l;i<strlen(buf);i++)
    { buf[i]=' ';}
    fprintf(OUTFILE, "%s \n",buf);
    }

    else fprintf(OUTFILE, "%s",buf);
    }

    fseek(INFILE, 0,0); // remise a zéro curseur

    // effacer les commentaires /*.....*/
    while(NULL != fgets(buf, sizeof buf,INFILE))
    {// le cas ou nous trouvons */ et /* sur la même linge
    if((NULL != strstr(buf, "/*"))&&(NULL != strstr(buf, "*/")))
    {{l=0;
    while((buf[l]!='/')&&(buf[l]!='\n')) // pour déterminer la position de la commentaire
    {buf[l]=' ';l++;}
    buf[l]=' ';i=0,l=0;
    }}
    l=0;i=0;
    // cas ou nous trouvons une chaine contient commentaire*/ ou/*commentaire
    if((NULL != strstr(buf, "/*"))||(NULL != strstr(buf, "*/")))
    {
    if(NULL != strstr(buf, "/*"))
    {while((buf[l]!='/')&&(buf[l]!='\n')) // pour déterminer la position de la commentaire /*
    {l++;}l--;
    i=strlen(buf)+1;
    while(i!=l)
    {buf[i]=' ';i--;}
    buf[l]=' '; i=0,l=0;fprintf(OUTFILE, "%s\n",buf);
    }

    // pour continuer a effacée les linges entre /*... et... */
    while((NULL != fgets(buf, sizeof buf,INFILE))&&(NULL != strstr(buf, "*/")))
    { fprintf(OUTFILE, "%s"," ");}
    printf("%s voila",buf);
    if(NULL != strstr(buf,"*/"))
    {while((buf[l]!='/')&&(buf[l]!='\n'))
    {l++;}
    while(i!=l+1)
    {buf[i]=' ';i++;}
    i=0,l=0;fprintf(OUTFILE, "%s\n",buf);
    }
    else fprintf(OUTFILE, "%s",buf);
    }
    }

    fclose(OUTFILE);
    fclose(INFILE);
    }
    printf(" \n !! bien,operation reussite !! \n ");
    return 0 ;
    }
    0
    1. fiddy Messages postés 441 Date d'inscription   Statut Contributeur Dernière intervention   1 847
       
      Bonjour,
      Ton code n'est vraiment pas agréable à lire. A chaque fois que tu postes sur ce forum, il faut utiliser les balises "code" (à droite du bouton souligné) pour garder l'indentation.
      Sinon par rapport au code :
      1/ pour les //, tu utilises strstr() puis tu fais une boucle while jusqu'à trouver le premier /. Ce n'est pas bon. Le commentaire se trouve au-delà de // pas de /.
      strstr() renvoie la position du "//", donc t'as plus qu'à écrire un '\n' dans le fichier (et non mettre plein d'espaces).

      2/Il ne faut pas faire d'autres fgets(). Il faut réutiliser le fgets() précédent.
      Tu cherches le premier /* avec strstr(), et tu supprimes tout jusqu'à rencontrer le premier */.
      0
    2. hafed22 Messages postés 9 Statut Membre
       
      bonjour fiddy ,

      pour les commentaires avec // je dois supprimée de / jusqu'à la fin

      pour votre 2/ remarque ,comment je peux passer à la ligne suivante dans le fichier sans utiliser fgets() ??
      0
    3. fiddy Messages postés 441 Date d'inscription   Statut Contributeur Dernière intervention   1 847
       
      pour les commentaires avec // je dois supprimée de / jusqu'à la fin
      1/Ok, alors dans ce cas, supprimer de l'emplacement de strstr() +1 jusqu'à la fin (un simple \n suffit). Si tu n'es pas convaincu, lis ceci :
      Imagine la ligne suivante dans ton fichier : a=5/2; //ceci est un commentaire
      Et maintenant réfléchis à ce que ton algorithme va faire...

      2/Beh, il passera à la ligne suivante lors de la prochaine itération...
      Voici la structure :
      TantQue Non Fin du fichier :
          LIRE LIGNE
          DETECTION de commentaire //
          DETECTION de commentaire /**/
      FinTantQue
      

      Toi avec ton fgets(), tu feras 2 fgets() par itération... Ce qui est faux.
      0
    4. hafed22 Messages postés 9 Statut Membre
       
      merci fiddy pour me répondre ,Vraiment... Merci :) !
      mais le problème dans le cas :
      instruction /*......commentaire : linge 1
      .............................: linge2
      ............... linge n */ instruction
      comment je peut déplacée le curseur pour effacer le reste des linges avant */ et pour garder cette position pour l'instruction
        LIRE LIGNE
      0
    5. fiddy Messages postés 441 Date d'inscription   Statut Contributeur Dernière intervention   1 847
       
      comment je peut déplacée le curseur pour effacer le reste des linges avant */ et pour garder cette position pour l'instruction
      Il ne faut pas le déplacer. Cette ligne sera compris dans buf, il te suffit donc de jouer avec strstr() et de ne pas écrire (ou mettre des espaces) ce qu'il y a entre buf[0] et strstr(buf,"*/");
      0
  11. armasousou Messages postés 1351 Statut Membre 83
     
    Quel interet de faire un programme pour ça quand ya déjà une commande linux pour le faire 0.0 ?
    -1
    1. hafed22 Messages postés 9 Statut Membre
       
      slt armasousou
      c'est un mini projet qui contient cet fonction
      0