IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Ecriture dans une chaine passée comme argument d'une fonction


Sujet :

C

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    4
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 4
    Points : 2
    Points
    2
    Par défaut Ecriture dans une chaine passée comme argument d'une fonction
    Bonjour,

    je travaille présentement à l'écriture d'un programme qui, entre autres choses, balaie du code HTML pour en retirer de l'information. Grosso Modo l'utilisateur entre des chaines de caractère, et puis le programme se charge d'aller extraire une page html spécifique, si une certaine condition n'est pas remplie, le programme offre a l'utilisateur d'entrer une nouvelle chaine (toujours de longueur 7)

    Donc quand on appelle la fonction on lui transmet une chaine presque complète, et elle ajoute elle même le '\0'

    voici le code de la fonction

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
     
     
    void completer(int* section,char cours[], char hor[][29][5],char n, char liste_cours[][9], int coursnum)
    	{
    	int i;
    	char url[200];
    	char ligne[120];
    	char* pointeur;
     
    	cours[7]='\0';
    	CreerURL(url,cours);
    	extraire(url,cours);
    	FILE* code=fopen(cours, "r");
    	do
    		pointeur=fgets(ligne,120,code);
    	while(pointeur!=NULL && strstr(ligne,"Section ")==NULL);
     
    /***************/
    	if(pointeur==NULL)
    		{
    		int rep=0;
    		fclose(code);
    		printf("le cours %s n'est pas offert! Voulez-vous le changer ? (1/0)\n",cours);
    		scanf("%d",&rep);
    		if(rep==1)
    			{
    			printf("entrez le nouveau code de cours : ");
    			scanf("%s",cours); /*ca semble etre ca qui bogue */
    			min_maj(nouveau_cours);
    			}
    		else return;
    		}
    /************************/
    	parcourir(hor,cours,&(*section),n);
    	verifier_sections(hor,&(*section));
    	fclose(code);
    	for(i=0;i<8;i++)
    		liste_cours[i][coursnum-1]=cours[i];
    	return;
    	}
    Et j'ai toujours sois une erreur de segmentation, sois un message du type
    *** glibc detected *** double free or corruption (!prev): 0x0805ecd8 ***

    La résolution de ce problème dépasse ma compétence de programmeur amateur

    Quelqu'un à une idée?

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Tu ne mets pas de limite de taille à ton scanf("%s")...
    Quelle est la taille de cours ?

    En plus, tu as deux fclose(code) ce qui rend ta fonction peu lisible.
    Et aussi, tu dois obligatoirement tester le retour de fopen(). Sache qu'appeler fclose() sur un pointeur nul est un comportement indéfini, contrairement à free()...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Candidat au Club
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    4
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 4
    Points : 2
    Points
    2
    Par défaut
    Merci beaucoup de la réponse

    cours est de taille 8 et la chaine qu'on lui passe sera toujours de longueur 7. avec le \0 ca fait 8. Ça semble un peu serré mais ce n'est pas un programme grand public : ca gère des horaires de cours (celui qui l'utilise est censé être un prof de maths à l'université) et c'est vraiment depuis que je j'ai mis le scanf que ça plante. J'ai essayé gets, fgets avec stdin comme entrée, et d'autres que j'oublie.

    Mon hypothèse était qu'il y avait un problème et que la fonction n'a pas le droit de remplir la chaine cours.

    Tu m'en apprends une sur free(). Mes profs de programmation nous montraient fclose seulement (j'ignore leurs motivations) alors je mets ça dans mon callepin. Je ne savais pas qu'on DEVAIT tester le fopen (ça marche très bien sans tester -- ce n'est peut-être pas dans les règles de l'art cependant). Le 2e fclose est louche, tu as raison, mais ça plante avant. Pour simplifier j'ai enlevé le bout de code qui ré-ouvre un autre fichier, encore appelé code, pour concentrer l'attention sur le problème!

    Merci

  4. #4
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Points : 5 360
    Points
    5 360
    Par défaut
    Citation Envoyé par Rubique Voir le message
    Tu m'en apprends une sur free(). Mes profs de programmation nous montraient fclose seulement (j'ignore leurs motivations) alors je mets ça dans mon callepin.
    Tes profs ne t'ont pas parlé de free() parce que vous n'avez certainement pas encore vu l'allocation dynamique. Attention: free() n'a rien à voir avec les fichier et fclose().

    Sinon, bien sûr que ça fonctionne dans la plupart des cas sans tester la valeur de retour de fopen(). C'est les cas où cela ne marche pas qu'il nous faut prévoir. On appelle cela la programmtion défensive. Se protéger contre les événement inattendus qui pourraient survenir.

    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  5. #5
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    Mon hypothèse était qu'il y avait un problème et que la fonction n'a pas le droit de remplir la chaine cours.
    C'est possible effectivement si dans l'appel tu as une chaîne littérale :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    completer(...,"math",...);
    // ou
    char *cours = "math"; 
    completer(...,cours,...);
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

  6. #6
    Candidat au Club
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    4
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 4
    Points : 2
    Points
    2
    Par défaut
    Donc si c'est un tableau de caractère que j'ai initialisé de cette facon :

    char cours1[10];

    ca ne devrait jamais causer de problème à l'écriture (sauf que je sors du tableau bien sur)?

  7. #7
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    En effet.

    Pour éviter ce genre de problèmes à l'avenir, si tu es sous gcc, je te conseille d'ajouter le paramètre -Wwrite-strings à tes options de compilation.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  8. #8
    Candidat au Club
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    4
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 4
    Points : 2
    Points
    2
    Par défaut merci à tous
    Je remercie tous ceux qui ont bien tenté de m'aider.

    Le bogue n'était pas dans la fonction que je vous ai présentée. La chaine était effectivement modifiée. Toutefois après avoir modifier j'aurais du ré-appeler les fonctions créeerURL et extraire pour recreer un certain fichier ayant exactement le même nom que la chaine.

    Comme une future fonction ayant comme argument cette chaine devait rouvrir un fichier ayant le nom de la chaine (et que ce fichier n'existait pas pour les raisons mentionnées) ... ca plantait

    la morale de l'histoire : celui qui m'a dit de toujours tester mes fopen a plus d'expérience que moi!

    merci encore

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 5
    Dernier message: 14/12/2013, 18h10
  2. Réponses: 1
    Dernier message: 25/07/2013, 12h39
  3. Réponses: 11
    Dernier message: 19/04/2011, 15h30
  4. Affichage bizzare d'une url passée comme argument
    Par Bruno.C dans le forum Langage
    Réponses: 3
    Dernier message: 30/01/2008, 18h39
  5. une url comme argument d'une fonction
    Par khayyam90 dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 18/10/2004, 20h15

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo