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 :

Tableau à double dimension


Sujet :

C

  1. #1
    Inactif   Avatar de Deallyra
    Profil pro
    Étudiant
    Inscrit en
    Février 2007
    Messages
    1 997
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2007
    Messages : 1 997
    Points : 1 769
    Points
    1 769
    Par défaut Tableau à double dimension
    Bonjour,

    J'ai un problème dans mon programme actuel et j'aurais souhaité que vous m'apportiez un peu d'aide.

    En fait, j'ai mon programme qui ressemble à ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    //Declaration des variables
    (...)
    //Traitement du main
    (...)
    //Declaration d'un tableau
    char tableauMachine[compteurTableauMachine][256];
    //Reprise du traitement du main
    (...)
    Un problème de "conscience" que j'avais quant à déclarer une variable au beau milieu d'un code s'est transformé en erreur révélée par le compilateur GCC.

    main.c:179: erreur: «tableauMachine» undeclared (first use in this function)
    Alors que ma déclaration est en ligne 106.

    Alors je me suis dit que je pouvais peut être pallier à ce problème via un malloc puis realloc.

    Mais je ne sais pas du tout comment l'utiliser par rapport à un tableau à double dimension...
    void *malloc (size_t size);
    void *realloc (void *ptr, size_t size);

    En fait, pour être plus précise quant à mon problème et la solution que j'avais choisi, il se trouve que j'ai un fichier que je devrais constamment ouvrir et fermer si je devais le garder tel quel, chose coûteuse en temps.
    Alors j'ai décidé de lire une première fois ce fichier, compter le nombre de ligne puis créer ce tableau, avec pour nombre de ligne celui du fichier, un nombre de colonne fixe (256, arbitraire)

    Mais ça ne marche pas

    Une idée?

  2. #2
    Membre du Club Avatar de Mayhem555
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    89
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 89
    Points : 46
    Points
    46
    Par défaut
    Salut.
    Pour faire une allocation dynamique d'un tableau en 2D, il faut faire une boucle avec des malloc.
    Un tableau à deux dimensions n'étant rien d'autre qu'un tableau de tableaux (ou un pointeur de pointeurs )

    Ça donne quelque chose du genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    char **tableau ;
    tableau = (char**) malloc (nbLignes*sizeof(char*)) ;
     
     
    for (i = 0 ; i < nbLignes ; i++)
    {
         *(tableau+i) = (char*) malloc (nbColonnes * sizeof (char)) ;
    }

  3. #3
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par Mayhem555 Voir le message
    Ça donne quelque chose du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    char **tableau ;
    tableau = (char**) malloc (nbLignes*sizeof(char*)) ;
     
     
    for (i = 0 ; i < nbLignes ; i++)
    {
         *(tableau+i) = (char*) malloc (nbColonnes * sizeof (char)) ;
    }
    A quoi servent tous ces casts ?

    En utilisant le principe :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    T *p = malloc (sizeof *p * n);
    ca donne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    char **tableau = malloc (nbLignes * sizeof *tableau);
     
    for (i = 0 ; i < nbLignes ; i++)
    {
         tableau[i] = malloc (nbColonnes * sizeof *tableau[i]);
    }
    tout simplement...

  4. #4
    Inactif   Avatar de Deallyra
    Profil pro
    Étudiant
    Inscrit en
    Février 2007
    Messages
    1 997
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2007
    Messages : 1 997
    Points : 1 769
    Points
    1 769
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    char **tableau = malloc (nbLignes * sizeof *tableau);
     
    for (i = 0 ; i < nbLignes ; i++)
    {
         tableau[i] = malloc (nbColonnes * sizeof *tableau[i]);
    }
    hum... Le premier malloc gère le nombre de ligne et le second dans le for, le nombre de colonne par ligne?

    à quoi correspond le " char **tableau" ?
    zero ou plusieurs caractères et un pointeur vers le tableau?

    J'aimerai comprendre plutôt que de reprendre bêtement du code ^^'


    Par contre... Sauriez vous si la déclaration d'une variable (en l'occurrence le tableau à deux dimensions) dans le corps du programme n'est effectivement pas prise en compte où s'il s'agit d'une autre erreur?

    Ceci dit, merci à vous deux.

  5. #5
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par Deallyra Voir le message
    hum... Le premier malloc gère le nombre de ligne et le second dans le for, le nombre de colonne par ligne?

    à quoi correspond le " char **tableau" ?
    zero ou plusieurs caractères et un pointeur vers le tableau?

    J'aimerai comprendre plutôt que de reprendre bêtement du code ^^'
    http://emmanuel-delahaye.developpez.....htm#tabdyn_2d
    Par contre... Sauriez vous si la déclaration d'une variable (en l'occurrence le tableau à deux dimensions) dans le corps du programme n'est effectivement pas prise en compte où s'il s'agit d'une autre erreur?
    B.A. BA du C : une variable doit être définie en début de bloc. On a le droit de définir un bloc où veut. La portée est définie par le bloc.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    f()
    {
       /* instructions ... */
       {
           int x;
           /* instructions ... */
       }
       /* instructions ... */
    }

  6. #6
    Inactif   Avatar de Deallyra
    Profil pro
    Étudiant
    Inscrit en
    Février 2007
    Messages
    1 997
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2007
    Messages : 1 997
    Points : 1 769
    Points
    1 769
    Par défaut
    En effet, j'étais en dehors du bloc où j'ai déclaré la variable...

    Merci pour ce rappel du B.A. BA
    Je ne le savais pas et ne l'avait pas encor lu...

    Merci pour le lien.

  7. #7
    Inactif   Avatar de Deallyra
    Profil pro
    Étudiant
    Inscrit en
    Février 2007
    Messages
    1 997
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2007
    Messages : 1 997
    Points : 1 769
    Points
    1 769
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    char **tableau = malloc (nbLignes * sizeof *tableau);
     
    for (i = 0 ; i < nbLignes ; i++)
    {
         tableau[i] = malloc (nbColonnes * sizeof *tableau[i]);
    }
    Je suis vraiment désolée... Mais je ne comprends pas réellement comment cela résoudra mon problème

    Si je veux que le tableau est une portée dans tout mon programme, il me faut alors le déclarer au début.

    Cependant, je ne pourrais pas fixer nbLignes...

    Est-il possible de faire ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    //au premier bloc, avec les autres déclarations de globales
    int i;
    char **tableau = malloc (1 * sizeof *tableau);
     
    // traitement
    (...)
     
    nbLignes = 123;
    tableau = malloc (nbLignes * sizeof *tableau);
    for (i = 0 ; i < nbLignes ; i++)
    {
         tableau[i] = malloc (256 * sizeof *tableau[i]);
    }

  8. #8
    Membre du Club Avatar de Mayhem555
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    89
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 89
    Points : 46
    Points
    46
    Par défaut
    Cela va t'aider dans le sens où il faut que tu remplisse un tableau dont tu ne connais pas la taille au moment de la compilation. Donc tu dois faire une allocation de mémoire ayant la bonne taille au moment de l'exécution (alloc dynamique).

    Déclare simplement ton pointeur au début.

    Jusqu'à présent, tu as juste créé un pointeur qui pointe vers une zone mémoire qui n'est pas allouée.

    Une fois que tu connais ton nombre de ligne, là tu peux faire l'allocation de mémoire.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    tableau = malloc (nbLignes * sizeof *tableau);
     
    for (i = 0 ; i < nbLignes ; i++)
    {
         tableau[i] = malloc (nbColonnes * sizeof *tableau[i]);
    }

  9. #9
    Inactif   Avatar de Deallyra
    Profil pro
    Étudiant
    Inscrit en
    Février 2007
    Messages
    1 997
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2007
    Messages : 1 997
    Points : 1 769
    Points
    1 769
    Par défaut
    Hum...

    J'ai du louper quelque chose...

    Je n'ai plus l'erreur mais un warning m'indiquant que tableauMachine n'est pas initialisé...

    Heu... Je vous montre le code :s
    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
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    ligne 91		////Traitement de la machine////
    		
    			if(fichierMachine != NULL)												//Ouverture du fichier reussie
    			{
    				////On cherche a connaitre la taille du tableau a reserver en memoire////
    					while(fgets(ligne, sizeof ligne, fichierMachine) != NULL)
    					{
    						if(ligne[0] != '$')											//Ligne de commentaire
    						{
    							compteurTableauMachine++;								//Incrementation du compteur
    						}
    					}
    					fclose(fichierMachine);											//Fermeture du fichier de donnees
    				
    					tableauMachine = malloc (compteurTableauMachine * sizeof *tableauMachine);
    					for (i = 0 ; i < compteurTableauMachine ; i++)
    					{
    						tableauMachine[i] = malloc (256 * sizeof *tableauMachine[i]);
    					}
    				
    				////On remplit le tableau////
    				fichierMachine = fopen("machine.txt", "r");							//Declaration et instanciation d'un pointeur de type fichier vers la machine
    				i = 0;																//Pour plus de clarté
    				while(fgets(ligne, sizeof ligne, fichierMachine) != NULL)
    				{																	//Tant que l'on peut lire une ligne du fichier et que la variable "booleene" finDonnees est a faux
    					caractere = ligne[0];											//Lecture du premier caractere de la ligne
    					if(caractere != '$')											//Ligne de commentaire
    					{
    						j = 0;														//Initialisation du compteur de caracteres
    						while (caractere != '\n')									//Verification de non fin de donnees atteinte
    						{
    							tableauMachine[i][j] = caractere;						//Ajout du caractere en derniere position de la liste
    							j++;													//Incrémentation de la position en colonne
    							caractere = ligne[j];
    						}
    						i++;														//Incrémentation de la position en ligne
    					}
    				}
    				
    				i = 0;
    				compteur = 0;														//Reinitialisation du compteur pour le nombre de #
    				while((i != compteurTableauMachine+1) && (compteur < 3))			//Parcourt du tableau jusqu'aux lignes d'etat initial et etat final
    				{
    					j = 0;
    					while((j <256) && (tableauMachine[i][j] != NULL) &&  compteur < 3)
    					{
    						if(tableauMachine[i][j] == '#')								//On compte le nombre de # rencontres, cela permettra de savoir si on arrive a l'etat initial et l'etat final
    						{
    							compteur++;												//Incrementation du compteur
    						}
    						j++;														//Incrementation du compteur colonne
    					}
    					i++;															//Incrementation du compteur ligne
    				}
    				for(j=0;tableauMachine[i][j] != NULL;j++)							//On  instancie la variable d'etat initial
    				{
    					etatInitial[j] = tableauMachine[i][j];
    				}
    				i++;
    				for(j=0;tableauMachine[i][j] != NULL;j++)							//On  instancie la variable d'etat final
    				{
    					etatFinal[j] = tableauMachine[i][j];
    				}
    				printf("[%c%c%c]__[%c%c%c]\n", etatInitial[0], etatInitial[1], etatInitial[2], etatFinal[0], etatFinal[1], etatFinal[2]);
    				
    				
    			}
    			else
    			{
    				if (feof(fichierMachine))											//Fin de fichier detectee
    				{
    					puts("\nFin du fichier machine atteinte.");
    				}
    					if (ferror(fichierMachine))										//Une erreur s'est produite
    				{
    					perror("machine.txt");
    				}
    			}
    			fclose(fichierMachine);													//Fermeture du fichier de donnees
    		////Fin de Traitement de la Machine
    
    		////Traitement des donnees par la machine
    
    			previewCurrent = listeDC->first->prev;									//Initialisation du pointeur vers l'element precedent de l'actuel
    			nextCurrent = listeDC->first->next;										//Initialisation du pointeur vers l'element suivant de l'actuel
    		
    			strcpy(etatActuel,etatInitial);											//On initialise l'état.
    
    			while(etatInitial != etatFinal)
    			{
    				i = 0;																//Réinitialisation du compteur Ligne
    				while((i <= compteurTableauMachine) && (ligneTrouvee == 0))			//Tant que je n'ai pas trouvé la bonne transition
    				{
    					j = 0;															//Réinitialisation du compteur Colonne
    					while(tableauMachine[i][j] != ' ')								//Récupération de l'etat de la ligne
    					{
    						etatLigne[j] = tableauMachine[i][j];
    						j++;
    					}
    					j++;
    					valeur = tableauMachine[i][j];									//Valeur de test
    					if((strcmp(etatLigne,etatInitial) == 0) && (current->value == valeur))
    					{
    						ligneTrouvee = 1;
    					}
    					else
    					{
    						i++;
    					}
    				}
    				if((strcmp(etatLigne,etatInitial) == 1) || (current->value != valeur))
    				{
    					puts("Erreur, fichier donnee non valide par rapport à la machine");
    				}
    				else
    				{
    					j += 2;
    					current->value = tableauMachine[i][j];							//Valeur à remplacer
    					j += 2;
    					while(tableauMachine[i][j] != ' ')								//Récupération de l'etat de la ligne
    					{
    						etatActuel[j] = tableauMachine[i][j];
    						j++;
    					}
    					j ++;
    					if(tableauMachine[i][j] == 'R')
    					{
    						current = current->next;
    					}
    					else
    					{
    						current = current->prev;
    					}
    				}
    			}
    		////Fin du Traitement des données par la Machine
    	
    			for (i=0; i <= compteurTableauMachine; i++)
    			{
    				free(tableauMachine[i]), tableauMachine[i] = NULL;
    			}
    			free(tableauMachine), tableauMachine = NULL;
    
    			Clear(listeDC);																	//On vide la liste
    			return 0;
    avec ces warnings :
    deallyra@rosenoire-desktop:~/L3IGS5/machineTuring/27-11@Turing$ make
    main.c:16: attention : function declaration isn»t a prototype
    main.c: Dans la fonction «main» :
    main.c:135: attention : comparaison entre un pointeur et un entier
    main.c:145: attention : comparaison entre un pointeur et un entier
    main.c:150: attention : comparaison entre un pointeur et un entier
    main.c:228: attention : ne sera jamais exécuté
    main.c:230: attention : ne sera jamais exécuté
    main.c:228: attention : ne sera jamais exécuté
    main.c:232: attention : ne sera jamais exécuté
    main.c:36: attention : «tableauMachine» may be used uninitialized in this function
    main.c:25: attention : «j» may be used uninitialized in this function
    main.c:41: attention : «current» may be used uninitialized in this function
    main.c:37: attention : «valeur» may be used uninitialized in this function
    J'aurais préféré ne pas avoir à mettre mon code :/
    Désolée.

  10. #10
    Membre du Club Avatar de Mayhem555
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    89
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 89
    Points : 46
    Points
    46
    Par défaut
    Tu peux initialiser ton pointeur tableau à NULL.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    char **tableau = NULL ;
    Qui spécifie explicitement "ce pointeur ne pointe vers rien" (du moins pour le moment )

  11. #11
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 381
    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 381
    Points : 41 582
    Points
    41 582
    Par défaut
    On peut faire moins de malloc() avec un code comme celui-ci :
    http://www.developpez.net/forums/m1803870-7/
    Par contre, ce code est clairement "tableau 2D" et absolument pas "tableau de tableau".

  12. #12
    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
    Quelques explications sur les avertissements :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    //main.c:135: attention : comparaison entre un pointeur et un entier
    while ((j <256) && (tableauMachine[i][j] != NULL) &&  compteur < 3)
     
    //main.c:145: attention : comparaison entre un pointeur et un entier
    for (j=0;tableauMachine[i][j] != NULL;j++)
     
    //main.c:150: attention : comparaison entre un pointeur et un entier	
     for (j=0;tableauMachine[i][j] != NULL;j++)
    tableauMachine[ i][j] est un entier et NULL un pointeur. Ces comparaisons ne sont pas normales. Il y a une erreur de conception. Si le tableau est terminé par la valeur 0, il faut écrire tableauMachine[ i][j] != 0

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    //main.c:228: attention : ne sera jamais exécuté
    //main.c:230: attention : ne sera jamais exécuté
    //main.c:228: attention : ne sera jamais exécuté
    //main.c:232: attention : ne sera jamais exécuté
    ....
    printf("[%c%c%c]__[%c%c%c]\n", etatInitial[0], etatInitial[1], etatInitial[2], etatFinal[0], etatFinal[1], etatFinal[2]);
    .....
    while (etatInitial != etatFinal)
    {
    ...
    }
    etatInitial et etatFinal semblent être deux tableaux, comme on le voit plus haut dans le printf.
    La comparaison dans le while compare les adresses de ces tableaux, pas leur contenu. La comparaison donnera toujours Vrai, et on ne sortira jamais du while. Les instructions derrière ne seront jamais exécutées.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    //main.c:36: attention : «tableauMachine» may be used uninitialized in this function
    //tableauMachine est initialisé par malloc dans le
    if (fichierMachine != NULL)
    Si on ne passe pas par ce if, tableauMachine n'est pas initialisé. Pourtant, on trouve plus loin tableauMachine[ i][j]. Le compilateur signale que dans ce cas, le comportement est indéfini.

    ....

  13. #13
    Inactif   Avatar de Deallyra
    Profil pro
    Étudiant
    Inscrit en
    Février 2007
    Messages
    1 997
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2007
    Messages : 1 997
    Points : 1 769
    Points
    1 769
    Par défaut
    @Mayhem555:

    Merci mais ceci est un placebo... Je l'aurais initialisé certes mais si le compilateur me dit présentement qu'il ne l'est pas, il sera simplement initialisé avec ce NULL que je rajouterai.
    Pas avec mes valeurs.

    @Médinoc :

    Merci pour la source, je vais regarder et voir si je trouve cela plus... compréhensible.

    @diogene :

    Merci beaucoup. Ca m'aide à progresser de m'indiquer quelles sont les erreurs de façon plus explicite.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    //main.c:135: attention : comparaison entre un pointeur et un entier
    while ((j <256) && (tableauMachine[i][j] != NULL) &&  compteur < 3)
    Mon tableau reçoit les caractères suivant pour une ligne (par exemple)
    q4 _ 1 q4 L
    Le dernier caractère pouvant actuellement être L ou R.
    Comment procéder alors de façon "propre" ?

    Rajouter un 0 après le L ou le R dans le tableau lors de l'instanciation ou alors m'arrêter au L/R et ensuite le lire en dehors de la boucle?
    (ou une autre idée que je n'ai pas eu )

    etatInitial et etatFinal semblent être deux tableaux, comme on le voit plus haut dans le printf.
    La comparaison dans le while compare les adresses de ces tableaux, pas leur contenu. La comparaison donnera toujours Vrai, et on ne sortira jamais du while. Les instructions derrière ne seront jamais exécutées.
    En fait, j'ai
    char etatInitial[3];
    char etatFinal[3];

    Il s'agit d'un etat représenté par le "q4", ne dépassant pas une taille de plus de 3 caractères... J'ai alors pensé à faire ainsi pour ne pas dépenser inutilement de l'espace mémoire.
    Je souhaiterai les comparer dans leur ensemble...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while(strcmp(etatInitial,etatFinal) == 0)
    est-il correct?

    Si on ne passe pas par ce if, tableauMachine n'est pas initialisé. Pourtant, on trouve plus loin tableauMachine[ i][j]. Le compilateur signale que dans ce cas, le comportement est indéfini.
    Je comprends mieux le problème maintenant...
    Dois-je mettre alors tout mon code suivant dans le bloc if? (celui qui utilise tableauMachine comme étant déjà initialisé) ou alors dois-je arrêter le programme suite à la détection de l'erreur?

  14. #14
    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
    [QUOTE]
    Il s'agit d'un etat représenté par le "q4", ne dépassant pas une taille de plus de 3 caractères... J'ai alors pensé à faire ainsi pour ne pas dépenser inutilement de l'espace mémoire.
    Je souhaiterai les comparer dans leur ensemble...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while(strcmp(etatInitial,etatFinal) == 0)est-il correct?
    Si etatInitial et etatFinal sont représentés par une chaîne de caractères standard (terminées par 0) oui !

    Dois-je mettre alors tout mon code suivant dans le bloc if? (celui qui utilise tableauMachine comme étant déjà initialisé) ou alors dois-je arrêter le programme suite à la détection de l'erreur?
    je ne peux répondre. Si l'erreur est récupérable, il faut écrire les dispositions pour, sinon, il n'y a plus qu'à arrêter tout.

  15. #15
    Inactif   Avatar de Deallyra
    Profil pro
    Étudiant
    Inscrit en
    Février 2007
    Messages
    1 997
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2007
    Messages : 1 997
    Points : 1 769
    Points
    1 769
    Par défaut
    Hum...

    Une chaîne de caractères sous forme de tableau est-elle une chaîne de caractères standard? :s

    (autrement dit, le fait de rajouter \0 en dernière position à la "chaîne-tableau" )

    Le fait est que je construis etatInitial et etatActuel par l'ajout successif de caractères.

    Mon if est en fait la simple vérification de la réussite du fopen du fichier que je passe dans un tableau.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    FILE *fichierMachine = fopen("machine.txt", "r");	//Declaration et instanciation d'un pointeur de type fichier vers la machine
    (...)
    if(fichierMachine != NULL)	//Ouverture du fichier reussie

  16. #16
    Inactif   Avatar de Deallyra
    Profil pro
    Étudiant
    Inscrit en
    Février 2007
    Messages
    1 997
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2007
    Messages : 1 997
    Points : 1 769
    Points
    1 769
    Par défaut
    Bonjour,

    J'ai réussi à corriger un bon nombre d'erreurs grâce à vos explications cependant, il m'en reste deux types.

    La première :
    main.c:16: attention : function declaration isn»t a prototype
    Se rapportant à :
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    int main() //ligne 15
    { //ligne 16

    L'autre type d'erreur a déjà été expliqué par Diogène... Mais je ne comprends pas pourquoi ça ne marche pas...
    main.c:38: attention : «tableauMachine» may be used uninitialized in this function
    main.c:25: attention : «j» may be used uninitialized in this function
    main.c:39: attention : «valeur» may be used uninitialized in this function
    main.c:43: attention : «current» may be used uninitialized in this function
    Ce qui correspond respectivement à :
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    	char **tableauMachine;
    	int i,j;
    	char valeur;
    	struct elem *current;

    Cependant, ces variables sont initialisées en tous cas... normalement...

    Je n'arrive pas à comprendre...

    Pourriez vous jeter un oeil au code suivant?
    Pièce jointe 38787

    Merci beaucoup

  17. #17
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par Deallyra Voir le message
    Se rapportant à :
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    int main() //ligne 15
    { //ligne 16
    Il manque un void pour signifier qu'il n'y a pas de paramètres :
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    int main(void)
    {
    L'autre type d'erreur a déjà été expliqué par Diogène... Mais je ne comprends pas pourquoi ça ne marche pas...


    Ce qui correspond respectivement à :
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    	char **tableauMachine;
    	int i,j;
    	char valeur;
    	struct elem *current;

    Cependant, ces variables sont initialisées en tous cas... normalement...
    Comment sont-elles initialisées ?

    Beaucoup d'erreurs dans le code. Notamment un mauvais usahe de strcat() qu ne fonctionne qu'avec des chaines, et une chaine de destination n'ayr=yant pas la taille suffisante (et en plus non modifiable. Je rappelle le bon usage de strcat() :

    1 - définir un tableau de char de destination d'une taille suffisante :

    char dest[128];

    2 - initialiser ce tableau de façon à ce qu'il contienne une chaine valide :

    strcpy (dest, "");

    3 - passer en 2ème paramètre une chaine valide, par exemple :
    "hello",
    p avec char const *p = "hello";
    ou
    s avec s[] = "hello";

    ce qui donne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    {
       char dest[128];
       char const *p = " world";
     
       strcpy (dest, "hello");
       strcat (dest, p);
     
    }

  18. #18
    Inactif   Avatar de Deallyra
    Profil pro
    Étudiant
    Inscrit en
    Février 2007
    Messages
    1 997
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2007
    Messages : 1 997
    Points : 1 769
    Points
    1 769
    Par défaut
    Hum... void... merci ><

    Par contre, pour la suite...

    Comment sont-elles initialisées ?
    "tableauMachine[i][j]" par ceci
    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
     
    while(fgets(ligne, sizeof ligne, fichierMachine) != NULL)
    {	//Tant que l'on peut lire une ligne du fichier et que la variable "booleene" finDonnees est a faux
    	caractere = ligne[0];//Lecture du premier caractere de la ligne
    	if(caractere != '$')//Ligne de commentaire
    	{
    		j = 0;//Initialisation du compteur de caracteres
    		while (caractere != '\n')//Verification de non fin de donnees atteinte
    		{
    			tableauMachine[i][j] = caractere;//Ajout du caractere en derniere position de la liste
    			j++;//Incrémentation de la position en colonne
    			caractere = ligne[j];
    		}
    		tableauMachine[i][j] = '0';//On rajoute 0 après L/R
    		i++;//Incrémentation de la position en ligne
    	}
    }
    avant la première utilisation (début initialisation 123 -> première utilisation 125)

    "j" par ceci
    avant la première utilisation (initialisation 142 -> première utilisation 165)

    valeur par ce code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    valeur = tableauMachine[i][j];//Valeur de test
    avant la première utilisation (initialisation 218 -> première utilisation 219)

    current par ce code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    current = listeDC->first;
    avant la première utilisation (initialisation 68 -> première utilisation 219)


    j'ai fait les changements suivants : (edit : pour les strcat)
    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
     
    char alphabet[256];
    char etats[256];
     
    ////On récupère l'alphabet et les etats////
    	j = 1;
    	fgets(ligne, sizeof ligne, fichierMachine);
    	strcpy(alphabet,&ligne[0]);
    	caractere = ligne[j];
    	while (caractere != '\n')//Verification de non fin de ligne
    	{
    		strcat(alphabet,&caractere);
    		j++;//Incrémentation de la position en colonne
    		caractere = ligne[j];
    	}
    	j = 1;
    	fgets(ligne, sizeof ligne, fichierMachine);
    	strcpy(etats,&ligne[0]);
    	caractere = ligne[j];
    	while (caractere != '\n')//Verification de non fin de ligne
    	{
    		strcat(etats,&caractere);
    		j++;//Incrémentation de la position en colonne
    		caractere = ligne[j];
    	}
    Est-ce correct ainsi?

  19. #19
    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
    main.c:38: attention : «tableauMachine» may be used uninitialized in this function
    Le compilateur indique que selon les conditions d'exécution, la variable peut être initialisée ou peut ne pas l'être (ce qui provoquera alors une erreur à l'exécution) :

    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
    if(fichierMachine!=NULL)					
    {
    ....				
       tableauMachine = malloc (compteurTableauMachine * sizeof *tableauMachine);
    }
    else
    {
    // Pas d'initialisation de tableauMachine
    }
    ....
    while(etatInitial != etatFinal)
    {
    ....
       while((i <= compteurTableauMachine) && (ligneTrouvee == 0))	
       {
    ....
         while(tableauMachine[i][j] != ' ')	
    // ici, tableauMachine n'est pas initialisé si on est passé par le else et non par le if.
    // c'est ce que signale le compilateur : Il est possible que tableauMachine[i][j] ne soit pas correct.
    Si on teste (à juste titre) que fichierMachine est différent de NULL, c'est aussi parce qu'on considère (à juste titre) qu'il peut ne pas l'être.
    Donc, le programme doit être correct dans les deux cas.

  20. #20
    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
    Ceci n'est pas correct :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    	caractere = ligne[j];
    	while (caractere != '\n')//Verification de non fin de ligne
    	{
    		strcat(alphabet,&caractere);
    strcat n'attend pas comme 2° argument l'adresse d'un caractère, mais l'adresse d'une chaîne de caractères, c'est à dire un tableau de caractères terminé par un 0.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. creation d'un tableau double dimension dynamiquement
    Par elmcherqui dans le forum C++
    Réponses: 3
    Dernier message: 09/07/2009, 20h05
  2. Tableau à double dimension
    Par 0635425 dans le forum Collection et Stream
    Réponses: 8
    Dernier message: 25/02/2008, 09h46
  3. Mettre un tableau à double dimension en session
    Par The Molo dans le forum ASP
    Réponses: 4
    Dernier message: 20/02/2008, 14h54
  4. Afficher un tableau à double dimension
    Par The Molo dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 20/02/2008, 12h37
  5. [FLASH MX] Tableau à double dimension
    Par totoche dans le forum Flash
    Réponses: 4
    Dernier message: 11/10/2005, 22h04

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