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

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    décembre 2020
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 20
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : décembre 2020
    Messages : 5
    Points : 5
    Points
    5
    Par défaut Programmes qui modifient leurs comportements dans les boucles if
    Bonsoir à tous,

    Pour un projet, je dois préparer un programme pouvant recevoir des arguments en ligne de commande depuis le shell. Voici le fichier main.c en question :
    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
    41
    42
    43
    44
    45
    46
    #include <stdio.h>
    #include <string.h>
     
    #include "definitions2.h"
     
    int main(int argc, char* argv[]) {
    	docShell("graph2.adj");
    	if (strcmp(argv[2],"-a")==0) { // entrée -a fichier .adj
    		if (strcmp(argv[1],"-dot")==0) { //sortie format .dot
    		T_graphMD* g=fileToGraph(argv[3]);
    		printf("argv[3] : _%s_\n",argv[3]);
    		char*filename=nomGraphe(argv[3],"dot");
    		printf("filename : _%s_\n",filename);
    		showGraph(filename, g);
    		docShell(filename);
    		}
    		else { // sortie format -la liste d'adjacence
    			T_graphMD* g=fileToGraph(argv[3]);
    			T_graphLA *g_=MDtoLA(g);
    			int i;
    			for (i=0;i<g_->nbVertices;i++) {
    				showList(g_->tAdj[i]);
    			}
    			char* filename=nomGraphe(argv[3],"la");
    			printf("filename : _%s_\n",filename);
    			LAtoFile(g_, filename);
    		}
    	}
    	if (strcmp(argv[2],"-l")==0) { // entrée -l fichier liste d'adjacence
    		if (strcmp(argv[1],"-dot")==0) { // sortie format .dot
    		T_graphLA* g=fileToLA(argv[3]);
    		T_graphMD * g_=LAtoMD(g);
    		char* filename=nomGraphe(argv[3],"ladot");
    		showGraph(filename, g_);
    		printf("filename : %s\n",filename);
    		docShell("graph2.adj"); //normalement c'est <<docShell(filename);>>, mais pour tester j'appelle la fonction avec ce fichier
    		}
     
    		else { // sortie format -adj
    			T_graphLA *g=fileToLA("./graph2.la");
    			T_graphMD *g_=LAtoMD(g);
    			char*filename=nomGraphe(argv[3],"adj");
    			graphToFile(g_,filename);
    		}
    	}
    }
    Il utilise de nombreux autres programmes mais le problème que je rencontre ne concerne que certains d'entre eux. Je pense que le problème est similaire pour chacun de mes soucis alors je vais d'abord vous en exposer un premier en espérant que sa résolution m'aide à corriger mes autres soucis.

    Prenons la fonction docShell appelée dès le début : elle recopie tout simplement sur le shell un fichier comme "graph2.dot" que je vous mets ci-dessous :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    0	9	3	i
    i	0	2	i
    i	i	0	4
    i	1	i	0
    Voici le code de docShell :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void docShell(const char* filename) {
    	FILE * fp=fopen(filename,"r");
    	CHECK_IF(fp = fopen(filename, "r"), NULL, "fopen docShell");
    	char c;
    	while ( (c=fgetc(fp)) != EOF) {
    		printf("%c", c);
    	}
    	fclose(fp);
    }
    Cette fonction est également appelée à la ligne 36 du fichier main.c. Voilà ce que je remarque : lorsque j'exécute main, par exemple avec la commande << ./main -dot -l ./graph2.la >>, un premier affichage de "graph2.adj" s'effectue correctement. Le second, en revanche (l'affiche demandé dans l'appel de la boucle if ligne 36) ne s'effectue pas. Pourtant, il s'agit du même fichier et mon fopen fonctionne.

    Avez-vous idée de ce qui pourrait causer cela ? Peut-être est-ce ma manière de gérer les lignes de commande ?

    Je vous remercie beaucoup pour vos éclairages, j'espère que mon message est suffisamment clair et je serai ravi de le préciser si besoin est.

    Vous souhaitant une bonne soirée,

    louisandrex

  2. #2
    Expert éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    décembre 2015
    Messages
    1 243
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : décembre 2015
    Messages : 1 243
    Points : 6 057
    Points
    6 057
    Par défaut
    Bonjour,

    Ton code ouvre 2 fois le fichier (ligne 2 et ligne 3), et ne le ferme qu'une fois!
    Et ligne 4, c est un char il est probable qu'il n'atteigne jamais la valeur EOF qui est un int pas un char, il faut le déclarer int.

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    décembre 2020
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 20
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : décembre 2020
    Messages : 5
    Points : 5
    Points
    5
    Par défaut
    Bonjour et merci dalfab !

    J'ai immédiatement corrigé le code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void docShell(const char* filename) {
    	FILE * fp;
    	CHECK_IF(fp = fopen(filename, "r"), NULL, "fopen docShell");
    	int c;
    	while ( (c=fgetc(fp)) != EOF) {
    		printf("%c", c);
    	}
    	fclose(fp);
    }
    Ceci m'a permis de vérifier toutes mes fonctions faisant appel à fopen() et j'ai bien vérifié que je fermais les fichiers en fin de programme. Le premier problème que je vous exposais semble résolu.

    Il me reste le problème suivant, avec ce main.c :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #include <stdio.h>
    #include <string.h>
     
    #include "definitions2.h"
     
    int main(int argc, char* argv[]) {
    	T_graphMD* g=fileToGraph(argv[3]);
    	char*filename=nomGraphe(argv[3],"dot");
    	showGraph(filename, g);
    	docShell(filename);
    }
    avec nomGraphe ainsi définie :
    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
    // Ce programme forme un nom pour les fichiers type à partir du nom du fichier en argument et du type "./graph1.adj","dot" renvoie "graph1.dot"
    char *nomGraphe(const char *filename,char *type){
      printf("argument nomGraphe : _%s_\n", filename);
    	int n =strlen(filename);
      int m =strlen(type);
      char *nom=malloc((n+m-1)*sizeof(char));
      for(int i=2;i<n;i++){
        if(filename[i]=='.'){
          nom[i-2]='.';
          break;
        }
        nom[i-2]=filename[i];
      }
      strcat(nom, type);
    	printf("résultat nomGraphe : _%s_\n", nom);
      return nom;
    }
    L'appel à nomGraphe renvoie cela : (j'indique l'argument et la réponse) Nom : screen.png
Affichages : 111
Taille : 5,3 Ko
    plutôt que simplement "graph2.dot". Ce qui s'insère entre "graph2" et ".dot" est des morceaux de "graph2.la" que voici :Pour info, voici fileToGraph :
    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
    41
    //fonction qui lit un document et crée la matrice correspondante : passer d'une entrée -a à une sortie -adj
    T_graphMD * fileToGraph(const char * filename) {
    	FILE* fpAdj=fopen(filename,"r");
     
    	CHECK_IF(fpAdj, NULL, "fopen fileToGraph");
     
    	// pour connaître la taille de la matrice, on compte le nombre de lignes dans fpAdj
    	unsigned int n=nbLignes(filename);
    	T_graphMD *g=newGraphMD(n);
    	int i=0,j=0;
    	char c;
     
    	// il faut maintenant remplir le Graph
    	while (c != EOF) {
    		c=fgetc(fpAdj);
    		if isdigit(c) {
    			ungetc(c, fpAdj);
    			fscanf(fpAdj,"%d",&g->mat[i][j++]);
    		}
    		else if (c=='\n') {
    			j=0;
    			i++;
    		}
    		else if (c=='i') {
    			j++;
    		}
     
    	}
     
    	//on vérifie :
    	printf("Vérification fileToGraph : \n");
    	for (i=0;i<n;i++) {
    		for (j=0;j<n;j++) {
    			printf("g->mat[%d][%d] : %d\n",i,j,g->mat[i][j]);
    		}
    	}
     
    	fclose(fpAdj);
     
    	return g;
    }
    Bizarrerie, avec ce main.c :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    int main(int argc, char* argv[]) {
    	//T_graphMD* g=fileToGraph(argv[3]);
    	char*filename=nomGraphe(argv[3],"dot");
    	//showGraph(filename, g);
    	//docShell(filename);
    }
    le programme nomGraphe fonctionne et me renvoie "graph2.dot", ce qui est voulu. Le soucis viendrait-il de fileToGraph ?

    Auriez-vous une autre idée de ce qui cause ce soucis ?

    Je vous remercie beaucoup pour votre aide qui m'a permis de corriger l'oubli des fclose() et a rétabli l'affichage sur le shell avec docShell !

    Bonne soirée !
    Images attachées Images attachées  

  4. #4
    Expert éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    décembre 2015
    Messages
    1 243
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : décembre 2015
    Messages : 1 243
    Points : 6 057
    Points
    6 057
    Par défaut
    Ligne 14, tu appelles strcat(). cette fonction permet de concatemer 2 chaines, ce qui sous-entend que les 2 chaines ont bien un terminateur. Mais ici nom n'en a pas!

  5. #5
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    février 2006
    Messages
    8 775
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : février 2006
    Messages : 8 775
    Points : 24 089
    Points
    24 089
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par louisandrex Voir le message
    (l'affiche demandé dans l'appel de la boucle if ligne 36) ne s'effectue pas.
    "if" n'est pas une boucle. Ou alors on n'a pas la même notion de ce qu'est une boucle.
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site

  6. #6
    Expert confirmé

    Inscrit en
    août 2006
    Messages
    3 841
    Détails du profil
    Informations forums :
    Inscription : août 2006
    Messages : 3 841
    Points : 5 413
    Points
    5 413
    Par défaut
    Bonjour,
    Citation Envoyé par Sve@r Voir le message
    Bonjour

    "if" n'est pas une boucle. Ou alors on n'a pas la même notion de ce qu'est une boucle.
    Je ne fais plus attention à ce genre d'erreur très répandue, ce qui bien entendu est très regrettable, et montre que quelque part la formation n'est pas au point ...

    ... mais je soupçonne les personnes qui écrivent ainsi soient autodidactes, et n'ont pas utilisé des sources correctes.
    "Mon pied droit est jaloux de mon pied gauche.
    Quand l'un avance, l'autre veut le dépasser.
    Et moi, comme un imbécile, je marche !"
    [Raymond Devos]

  7. #7
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    février 2006
    Messages
    8 775
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : février 2006
    Messages : 8 775
    Points : 24 089
    Points
    24 089
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par droggo Voir le message
    ... mais je soupçonne les personnes qui écrivent ainsi soient autodidactes, et n'ont pas utilisé des sources correctes.
    D'où notre rôle que de les rectifier
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site

  8. #8
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    décembre 2020
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 20
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : décembre 2020
    Messages : 5
    Points : 5
    Points
    5
    Par défaut
    Bonsoir et merci à tous,

    D'abord, je me permets de vous rassurer : j'ai parlé de boucle "if" et de toute évidence il s'agit d'une erreur grotesque. Mes professeurs m'ont correctement instruit et mon inattention n'a pas su leur faire honneur, puissent-ils me le pardonner.

    Il s'agissait bien d'une erreur relative au caractère '\0'.

    Je vous remercie pour votre aide et l'attention portée à mon problème,

    Vous souhaitant bonne soirée,

    louisandrex.

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

Discussions similaires

  1. Logiciel fantome qui continue d'apparaitre dans les programmes a desintallés
    Par tanaka59 dans le forum Dépannage et Assistance
    Réponses: 2
    Dernier message: 25/07/2019, 10h00
  2. Réponses: 12
    Dernier message: 13/03/2016, 22h50
  3. Réponses: 1
    Dernier message: 08/04/2012, 04h24
  4. Réponses: 3
    Dernier message: 20/09/2006, 23h35
  5. Réponses: 1
    Dernier message: 20/12/2005, 20h50

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