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 -
[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 ;
}
#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:
- Eleminé les commentaire dont un fichier c ?
- Fichier bin - Guide
- Comment réduire la taille d'un fichier - Guide
- Comment ouvrir un fichier epub ? - Guide
- Fichier rar - Guide
- Fichier .dat - Guide
10 réponses
Quelque chose comme cela devrait aller pour traiter les /* */ :
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
+------------------+ |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
Bonsoir,
Des accolades étaient mal placées, mais peut-être pas que ça .. a tester et nous dire si ça fonctionne ou non:
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 ; }
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
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
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
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
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
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 ;
}
#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 ;
}
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
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
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 ;
}
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 ;
}
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 */.
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 */.
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 :
Toi avec ton fgets(), tu feras 2 fgets() par itération... Ce qui est faux.
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.
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
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
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,"*/");
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,"*/");