Eleminé les commentaire dont un fichier c ?

hafed22 Messages postés 9 Date d'inscription   Statut Membre Dernière intervention   -  
[Dal] Messages postés 6205 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 ;
}
A voir également:

10 réponses

[Dal] Messages postés 6205 Date d'inscription   Statut Contributeur Dernière intervention   1 105
 
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
Heliotte Messages postés 1491 Date d'inscription   Statut Membre Dernière intervention   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
hafed22 Messages postés 9 Date d'inscription   Statut Membre Dernière intervention  
 
merci, mais çà reste le même problème "le programme cesse de fonctionner "
0
Char Snipeur Messages postés 9813 Date d'inscription   Statut Contributeur Dernière intervention   1 299
 
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
[Dal] Messages postés 6205 Date d'inscription   Statut Contributeur Dernière intervention   1 105
 
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

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
hafed22 Messages postés 9 Date d'inscription   Statut Membre Dernière intervention  
 
merci pour vos réponse ,mais s.v.p est ce que vous pouvez corriger mon code !?
0
Char Snipeur Messages postés 9813 Date d'inscription   Statut Contributeur Dernière intervention   1 299
 
je t'ai déjà indiqué des erreurs et comment les corrigées en partie. Met le code modifié, on verra après.
0
hafed22 Messages postés 9 Date d'inscription   Statut Membre Dernière intervention  
 
s.v.p ça n'a pas marché !! ? :(
0
Char Snipeur Messages postés 9813 Date d'inscription   Statut Contributeur Dernière intervention   1 299
 
développe
0
hafed22 Messages postés 9 Date d'inscription   Statut Membre Dernière intervention  
 
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
hafed22
 
s.v.p me répondre !!
0
[Dal] Messages postés 6205 Date d'inscription   Statut Contributeur Dernière intervention   1 105
 
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
hafed22 Messages postés 9 Date d'inscription   Statut Membre Dernière intervention  
 
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
fiddy Messages postés 11069 Date d'inscription   Statut Contributeur Dernière intervention   1 846
 
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
hafed22 Messages postés 9 Date d'inscription   Statut Membre Dernière intervention  
 
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
fiddy Messages postés 11069 Date d'inscription   Statut Contributeur Dernière intervention   1 846
 
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
hafed22 Messages postés 9 Date d'inscription   Statut Membre Dernière intervention  
 
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
fiddy Messages postés 11069 Date d'inscription   Statut Contributeur Dernière intervention   1 846
 
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
armasousou Messages postés 1268 Date d'inscription   Statut Membre Dernière intervention   83
 
Quel interet de faire un programme pour ça quand ya déjà une commande linux pour le faire 0.0 ?
-1
hafed22 Messages postés 9 Date d'inscription   Statut Membre Dernière intervention  
 
slt armasousou
c'est un mini projet qui contient cet fonction
0