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 :

initialisation et manipulation de tableau dynamique dans des structs


Sujet :

C

  1. #1
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2018
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2018
    Messages : 11
    Points : 2
    Points
    2
    Par défaut initialisation et manipulation de tableau dynamique dans des structs
    Bonsoir !

    je suis en train d'implementer des prototypes de fonctions deja donnés, j'ai plus ou moins du mal avec les pointeurs de tableaux et de fonctions.
    J'aurai besoin que vous verifiez, si possible, mon code, en particulier avec les *
    A vrai dire, je ne sais pas comment les tester avec un main etant donné que c'est une suite de fichiers (un projet en realisation), et que j'en suis qu'au debut.

    Voici le fichier file.h donné, je dois rajouter des prototypes de fonctions mais pas modifier ceux deja presents
    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
    // mettre des choses avant
    #define MIN(a,b) (((a)<(b))?(a):(b))
    #define MAX(a,b) (((a)>(b))?(a):(b))
     
    /// \struct pour encapsuler des tableaux dynamiques d'entiers avec la dimension.
    typedef struct s_tab_dyn{
      int * tab;
      int dim;
    } t_tab_int_dyn;
     
    typedef struct s_mat_dyn{
      int ** tab;
      int nbRows;
      int nbCol;
    } t_mat_int_dyn;
     
    /// \struct idem avec des chaînes de cractères
    typedef struct s_mat_char_dyn{
      char *** tab;
      int nbRows;
      int nbCol;
      int offset; // donne le nombre de colonnes avant celles des candidats
    } t_mat_char_star_dyn;
     
    /// \struct arc pour les graphes
    typedef struct s_arc_p{ /// arc pondéré
      int orig;
      int dest;
      int poids;
    } t_arc_p;
     
    int * creer_tab_int(int dim); // juste un malloc de dim cases
    int ** creer_mat_int(int nbRows,int nbCol); // malob 2D
    int ** creer_mat_char(int nbRows, int nbCol);
    void affiche_tab_int(int *tab,int dim, FILE *logfp);
     
    void creer_t_mat_int_dyn(t_mat_int_dyn *stTab,int nbRows,int nbCol); // utilise la struct
    void creer_t_tab_int_dyn(t_tab_int_dyn *stTab,int dim); // idem
    void creer_t_mat_char_dyn(t_mat_char_star_dyn * s_tabmots);
    void affiche_t_tab_int_dyn(t_tab_int_dyn t_tab, FILE *logfp);
    void affiche_t_mat_char_star_dyn(t_mat_char_star_dyn t_tabmots, FILE *logfp);
    void affiche_t_mat_int_dyn(t_mat_int_dyn t_tab, FILE *logfp);
    void affiche_mat_int(int **duels_mat,int nbRows,int nbCol,FILE *logfp);
     
    void init_tab_int(int *tab,int dim,int valeur);// initialise avec une valeur
    void init_mat_int(int **mat,int nbRows,int nbCol,int valeur); // idem
     
    //----------------------------------
    // Prototypes rajoutées par moi meme
    char lecture(char f, char delimiteur);
    void affiche_mat_char(char **duels_mat,int nbRows,int nbCol,FILE *logfp);
    et voici ce que j'ai fait, le fichier file.c
    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
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    #include <stdio.h>
    #include <stdbool.h>
    #include <string.h>
    #include "file.h"
    #define TAILLE_MAX 1000
     
     
    int * creer_tab_int(int dim)
    {
    	int *tab = NULL;
    	tab = malloc(dim*sizeof(int));
    	if (tab == NULL){
    		printf("Probleme d'allocation.\n");
    		exit(1);
    	}
    	return tab;
    }
     
    //----------------------------------------------------------------------------
     
    int ** creer_mat_int(int nbRows, int nbCol)
    {
    	int *tab = NULL;
    	tab = malloc(nbRows*sizeof(int));
    	if (tab == NULL){
    		printf("Probleme d'allocation.\n");
    		exit(1);
    	}
     
    	for (int i=0; i<nbRows; i++)
    	{
    		tab[i] = malloc(nbCol*sizeof(int));
    		if (tab[i] == NULL)
    		{
    			printf("Probleme d'allocation.\n");
    			exit(1);
    		}
    	}
    	return tab;
    }
     
    //----------------------------------------------------------------------------
     
    int ** creer_mat_char(int nbRows, int nbCol)
    {
    	char *tab = NULL;
    	tab = malloc(nbRows*sizeof(char*));
    	if (tab == NULL){
    		printf("Probleme d'allocation.\n");
    		exit(1);
    	}
     
    	for (int i=0; i<nbRows; i++)
    	{
    		tab[i] = malloc(nbCol*sizeof(char*));
    		if (tab[i] == NULL)
    		{
    			printf("Probleme d'allocation.\n");
    			exit(1);
    		}
    	}
    	return tab;
    }
     
    //----------------------------------------------------------------------------
     
    void creer_t_tab_int_dyn(t_tab_int_dyn *stTab, int dim)
    {
    	*stTab->tab = creer_tab_int(dim);
    }
     
    //----------------------------------------------------------------------------
     
    void creer_t_mat_int_dyn(t_mat_int_dyn *stTab, int nbRows, int nbCol)
    {
    	**stTab->tab = creer_mat_int(nbRows,nbCol);
    }
     
    //----------------------------------------------------------------------------
     
    void creer_t_mat_char_dyn(t_mat_char_star_dyn *s_tabmots)
    {
    	***s_tabmots->tab = creer_mat_char(s_tabmots->nbRows, s_tabmots->nbCol);
    }
     
    //----------------------------------------------------------------------------
     
    void affiche_tab_int(int *tab, int dim, FILE *logfp)
    {
    	for (int i=0; i<dim; i++)
    	{
    		fputs(tab[i],logfp);
    	}
    }
     
    //----------------------------------------------------------------------------
     
    void affiche_mat_int(int **duels_mat,int nbRows,int nbCol,FILE *logfp)
    {
    	for (int i=0; i<nbRows; i++)
    	{
    		for (int j=0; j<nbCol; j++)
    		{
    			fputs(duels_mat[i][j],logfp);
    		}
    	}
    }
     
    //----------------------------------------------------------------------------
     
    void affiche_mat_char(char **duels_mat,int nbRows,int nbCol,FILE *logfp)
    {
    	for (int i=0; i<nbRows; i++)
    	{
    		for (int j=0; j<nbCol; j++)
    		{
    			fputs(duels_mat[i][j],logfp);
    		}
    	}
    }
     
    //----------------------------------------------------------------------------
     
    void affiche_t_tab_int_dyn(t_tab_int_dyn t_tab, FILE *logfp)
    {
    	affiche_tab_int(*t_tab.tab,t_tab.dim,logfp);
    }
     
    //----------------------------------------------------------------------------
     
    void affiche_t_mat_int_dyn(t_mat_int_dyn t_tab, FILE *logfp)
    {
    	affiche_mat_int(**t_tab.tab,t_tab.nbRows,t_tab.nbCol,logfp);
    }
     
    //----------------------------------------------------------------------------
     
    void affiche_t_mat_char_star_dyn(t_mat_char_star_dyn t_tabmots, FILE *logfp)
    {
    	affiche_mat_char(***t_tabmots.tab,t_tabmots.nbRows,t_tabmots.nbCol,logfp);
    }
     
    //----------------------------------------------------------------------------
     
    void init_tab_int(int *tab,int dim,int valeur)
    {
    	for (int i=0; i<dim; i++)
    	{
    		tab[i] = valeur;
    	}
    }
     
    //----------------------------------------------------------------------------
     
    void init_mat_int(int **mat,int nbRows,int nbCol,int valeur)
    {
    	for (int i=0; i<nbRows; i++)
    	{
    		for (int j=0; j<nbCol; j++)
    		{
    			mat[i][j] = valeur;
    		}
    	}
    }
     
    //----------------------------------------------------------------------------
     
    char lecture(char f, char delimiteur)
    {
    	int i = 0;
    	int j;
    	int nbRows = 1;
    	int nbCol = 1;
    	char p;
    	char chaine [TAILLE_MAX] = "";
     
    	char **tab = NULL;
    	tab = malloc(nbRows*sizeof(char*));
    	if (tab == NULL){
    		printf("Probleme d'allocation.\n");
    		exit(1);
    	}
     
    	for (int i=0; i<nbRows; i++)
    	{
    		tab[i] = malloc(nbCol*sizeof(char));
    		if (tab[i] == NULL)
    		{
    			printf("Probleme d'allocation.\n");
    			exit(1);
    		}
    	}
     
    	FILE* fichier = NULL;
    	fichier = fopen(f,"r");
     
    	if (fichier == NULL)
    	{
    		printf("impossible d'ouvrir le fichier %c.",f);
    	}
    	else
    	{
    		while (fgets(chaine,TAILLE_MAX,fichier) != NULL)
    		{
    			j = 0;
    			p = strtok(chaine,delimiteur);
    			while (p != NULL)
    			{
    				tab[i][j] = p;
    				nbCol++;
    				tab[i] = realloc(tab[i],nbCol*sizeof(char));
    				if (tab[i] == NULL){
    					printf("Probleme d'allocation.\n");
    					exit(1);
    				}
    				p = strtok(NULL,delimiteur);
    				j++;
    			}
    			nbRows++;
    			tab = realloc(tab,nbRows*sizeof(char));
    			if (tab == NULL){
    				printf("Probleme d'allocation.\n");
    				exit(1);
    			}
    			i++;
    		}
    	}
    	fclose(f);
    	return tab;	
    }
    Les procedures utilisant les struct doivent utiliser les fonctions deja implementé

    Concernant la derniere fonction (char lecture) :
    elle doit lire un fichier txt, détecter le nombre de lignes (nbRows) et de colonnes (nbCol) en utilisant un caractère délimiteur passé en paramètre et doit renvoyer l’adresse d’un tableau de chaînes de caractères de nbrows × nbCol cases contenant chacun des éléments du fichier txt

    Je pense m’être tromper au niveau des parametres de la fonction, je ne sais pas trop

    Merci en tout cas et bon reveillon !

  2. #2
    Membre régulier Avatar de ekieki
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Avril 2014
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 65
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Enseignant Chercheur

    Informations forums :
    Inscription : Avril 2014
    Messages : 34
    Points : 103
    Points
    103
    Par défaut
    Citation Envoyé par Gayura Voir le message
    Concernant la derniere fonction (char lecture) :
    elle doit lire un fichier txt, [...]

    Je pense m’être tromper au niveau des parametres de la fonction, je ne sais pas trop
    Pour le savoir, le bon moyen c'est que tu écrives une fonction test_lecture(), qui lit un fichier de données charge tout ça dans une structure, et en fait afficher le contenu.

    Tester, c'est pas un truc qu'on fait plus tard, une fois qu'on a tout écrit. L'écriture des tests FAIT PARTIE du travail normal de programmation. Ca se fait en même temps que l'écriture des fonctions, ou encore mieux, avant.

    Il y a un intérêt à plusieurs niveaux
    • on ne se retrouve pas à chercher un bug dans les 500 lignes de code qu'on vient de pondre, ce qui est assez désagréable. On teste chaque fonction dès qu'elle est écrite, et quand il y a un truc qui ne va pas, c'est généralement dans les dernières lignes qu'on vient d'ajouter. On trouve beaucoup plus vite les erreurs.
    • psychologiquement, on va avoir des petits succès (ayé la fonction marche !) à intervalles réguliers, ce qui est excellent pour le moral. Contrairement à la recherche du minuscule bug dans une botte de foin, qui est désespérante.

  3. #3
    Expert éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 564
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    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 564
    Points : 7 640
    Points
    7 640
    Par défaut
    Bonjour,

    il manque une étoile après int ou char lignes 23 et 24 et 47 et 55.
    il en manque 2 ligne 46.
    Il y en a une de trop ligne 69, et il manque peut-être d'autre lignes dans cette fonction.
    ...
    C'est assez simple de vérifier (le compilateur le signale par un warning, sauf dans les sizeof où il faut compter sur une relecture soigneuse.)

  4. #4
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2018
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2018
    Messages : 11
    Points : 2
    Points
    2
    Par défaut
    Merci a tous pour vos reponses.
    Desole d'avoir pris du retard pour repondre.

    La je me suis concentré d'abord sur la fonction lecture, je suis arrivé a un resultat faux.
    j'ai fait un main qui utilise le fichier "marche.txt", je rappelle que la fonction doit lire un fichier txt, détecter le nombre de lignes (nbRows) et de colonnes (nbCol) en utilisant un caractère délimiteur passé en paramètre et doit renvoyer l’adresse d’un tableau de chaînes de caractères de nbrows × nbCol cases contenant chacun des éléments du fichier txt

    Voici le code :
    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
    #include <stdio.h>
    #include <stdbool.h>
    #include <string.h>
    #include <stdlib.h>
     
    #define TAILLE_MAX 1000
     
    //-------------------------------------------------
     
    char ***lecture(FILE *f, const char *delimiteur)
    {
    	int i = 0;
    	int j;
    	int nbRows = 0;
    	int nbCol = 0;
    	char *p;
    	char chaine[TAILLE_MAX];
     
    	char ***tab = NULL;
    	tab = malloc(nbRows*sizeof(char**));
    	if (tab == NULL){
    		printf("Probleme d'allocation.\n");
    		exit(1);
    	}
     
     
    	while (fgets(chaine,TAILLE_MAX,f) != NULL)
    	{
    		nbRows++;
    		nbCol = 0;
    		j = 0;
    		tab = realloc(tab,nbRows*sizeof(char**));
    		if (tab == NULL){
    			printf("Probleme d'allocation.\n");
    			exit(1);
    		}
     
    		tab[i] = malloc(nbCol*sizeof(char*));
    		if (tab[i] == NULL){
    			printf("Probleme d'allocation.\n");
    			exit(1);
    		}
     
    		p = strtok(chaine,delimiteur);
    		while (p != NULL)
    		{
    			nbCol++;
    			tab[i] = realloc(tab[i],nbCol*sizeof(char*));
    			if (tab[i] == NULL){
    				printf("Probleme d'allocation.\n");
    				exit(1);
    			}
    			tab[i][j] = p;
    			j++;
    			p = strtok(NULL,delimiteur);
    		}
    		i++;
    	}
     
     
    	for (int i=0; i<nbRows; i++)
    	{
    		for (int j=0; j<nbCol; j++)
    		{
    			printf("%s ",tab[i][j]);
    		}
    	}
     
    	fclose(f);
    	return tab;	
    }
     
     
    int main(){
    	const char *d = " ";
            FILE *fichier = NULL;
    	fichier = fopen("marche.txt", "r");
     
    	lecture(fichier,d);
     
    	return 0;
    }
    le fichier marche.txt possede ces lignes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Ceci est la 1ere ligne
    Ceci est la 2eme ligne
    Ceci est la 3eme ligne
    le programme m'affiche ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Ceci est la 3eme ligne
    Ceci est la 3eme ligne
    Ceci est la 3eme ligne
    Je ne vois pas trop d'ou ca vient ... on dirait qu'il ecrase a chaque fois les meme cases du tableau.
    merci bien

  5. #5
    Membre régulier Avatar de ekieki
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Avril 2014
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 65
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Enseignant Chercheur

    Informations forums :
    Inscription : Avril 2014
    Messages : 34
    Points : 103
    Points
    103
    Par défaut
    [Affichage de 3 fois la même chose] : c'est ce qui arrive quand on a un tableau dont les 3 éléments conduisent à la même chaine : le tampon dans lequel on fait les lectures. Et qui contient, justement, celle qui correspond à la dernière ligne.

    Conseil : réécris ton code calmement, en partant de zero. Avec ton char ***tab; et tes allocations dynamiques, tu ne sais pas où tu vas.

    Séparer en actions, représentées par des fonctions différentes

    • lire une ligne de texte dans un fichier (better use getline...)
    • à partir d'une chaine, fabriquer une structure correspondant à un enregistrement
    • l'ajouter dans une tableau de structures

  6. #6
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2018
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2018
    Messages : 11
    Points : 2
    Points
    2
    Par défaut
    J'ai revu mon code, il y'avait des malloc inutiles que j'ai enlevé, sinon j'ai toujours le meme resultat, qui est l'affichage de 3 fois la troisieme ligne du fichier, sans savoir d'ou ca vient.

    Ceci est un travail encadré, je ne pense pas devoir creer une autre structure de donnée, je dois juste creer une fonction qui prends en parametre un fichier txt et un caractere delimiteur, elle doit retourner l'adresse d'un tableau dynamique(de nbRows * nbCol) qui est realloué au fur et a mesure (cela depends du nombres de lignes (nbRows) du fichier et du nombre de mots (nbCol) par lignes)

    Voici mon code mis a jour :
    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
    #include <stdio.h>
    #include <stdbool.h>
    #include <string.h>
    #include <stdlib.h>
     
    #define TAILLE_MAX 1000
     
    //-------------------------------------------------
     
    char ***lecture(FILE *f, const char *delimiteur)
    {
    	int i = 0;
    	int j;
    	int nbRows = 0;
    	int nbCol = 0;
    	char *p;
    	char chaine[TAILLE_MAX];
     
    	char ***tab = NULL;
     
    	while (fgets(chaine,TAILLE_MAX,f) != NULL)
    	{
    		nbRows++;
    		nbCol = 0;
    		tab = realloc(tab,nbRows*sizeof(char**));
    		if (tab == NULL){
    			printf("Probleme d'allocation.\n");
    			exit(1);
    		}
     
    		p = strtok(chaine,delimiteur);
    		while (p != NULL)
    		{
    			nbCol++;
    			tab[nbRows-1] = realloc(tab[nbRows-1],nbCol*sizeof(char*));
    			if (tab[nbRows-1] == NULL){
    				printf("Probleme d'allocation.\n");
    				exit(1);
    			}
    			tab[nbRows-1][nbCol-1] = p;
    			p = strtok(NULL,delimiteur);
    		}
    	}
     
    	printf ("lignes = %d, ",nbRows);
    	printf("colonnes = %d\n",nbCol);
    	for (int i=0; i<nbRows; i++)
    	{
    		for (int j=0; j<nbCol; j++)
    		{
    			printf("%s ",tab[i][j]);
    		}
    	}
     
    	fclose(f);
    	return tab;	
    }
     
     
    int main(){
    	const char *d = " ";
            FILE *fichier = NULL;
    	fichier = fopen("marche.txt", "r");
     
    	lecture(fichier,d);
     
    	return 0;
    }

  7. #7
    Membre régulier Avatar de ekieki
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Avril 2014
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 65
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Enseignant Chercheur

    Informations forums :
    Inscription : Avril 2014
    Messages : 34
    Points : 103
    Points
    103
    Par défaut
    Citation Envoyé par Gayura Voir le message
    J'ai revu mon code, il y'avait des malloc inutiles que j'ai enlevé, sinon j'ai toujours le meme resultat, qui est l'affichage de 3 fois la troisieme ligne du fichier, sans savoir d'ou ca vient.

    Ceci est un travail encadré, je ne pense pas devoir creer une autre structure de donnée, je dois juste creer une fonction qui prends en parametre un fichier txt et un caractere delimiteur, elle doit retourner l'adresse d'un tableau dynamique(de nbRows * nbCol) qui est realloué au fur et a mesure (cela depends du nombres de lignes (nbRows) du fichier et du nombre de mots (nbCol) par lignes)
    La cause du problème, en remontant

    - ligne 40 : ce que tu stockes dans tab[machin][truc] vient du pointeur p
    - le pointeur p contient des adresses obtenues par strtok lignes 41 et 31
    - ligne 31 : strtok retourne des adresses à l'intérieur de la chaine
    - ligne 17 : chaine est une variable locale de la fonction lecture

    En résumé, ce que tu mets dans ton tableau, c'est des adresses qui sont comprises entre chaine et chaine+TAILLE_MAX. Toujours dans le même coin de la mémoire. C'est pour ça que tu vois toujours le même résultat pour tes trois enregistrements.

    Problème supplémentaire : ces adresses sont invalides dès qu'on sort de la fonction, puisqu'elles font référence à une variable locale qui a disparu. Mais tu ne t'en rends pas compte parce que tu lances tes affichages depuis la fonction, quand la variable locale existe encore. Ca va bugger sévère, plus loin.

    Correction :

    En fait ce que tu dois stocker dans t[machin][truc], c'est des COPIES des chaines de caractères qui ont été isolées par strtok.

    En faisant

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    tab[machin][truc] = strdup(p);           // POSIX / XOPEN_SOURCE
    ça devrait aller mieux.


    ---------

    PS: pour compléter.

    1. Les lignes 44 à 56 n'ont rien à faire là. Le rôle de la fonction lecture n'est pas d'afficher. Hop, dehors, 12 ligne en moins

    2. La boucle de lecture devrait faire appel à une fonction auxiliaire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     while (fgets(chaine,TAILLE_MAX,f) != NULL)
    	{
    	     nbRows++;
                 tab = realloc(tab, nbRows * sizeof(char**));
                 tab[nbrows - 1 ] = decoupage_ligne(chaine, delimiteur);
           }

    avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    char **decoupage_ligne(char * chaine, const char delimiteur)
    {
       int nbCol = 0;
       char **row = NULL;
       for ( char *champ = strtok(chaine, delimiteur);  champ != NULL;  champ = strtok(NULL, delimiteur) ) {
            nbCol++;
            row  = realloc(row, nbCol*sizeof(char*));
           // .. vérifier...
           row[nbCol - 1] = strdup(champ);		
       }
       return rows;
    }
    C'est pas plus simple comme ça ?

  8. #8
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    Le realloc !

  9. #9
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2018
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2018
    Messages : 11
    Points : 2
    Points
    2
    Par défaut
    Merci !!
    Effectivement, la probleme venait de tab[nbRows-1][nbCol-1]=p, plus de problème a present !

    Pour la partie printf, je sais bien, c'etait juste pour afficher le contenu et tester si ca l'affichait convenablement, j'avoue que j'aurai pu le mettre dans le main mais bon j'ai enlevé la partie printf et le main (j'utilise la fonction lecture dans un autre fichier)

    Le fait de decomposer la fonction est pas mal aussi, ca clean plus le code je suis d'accord.

    Autre chose, en oubliant cette fonction lecture, serait-il possible de récupérer le nombre de lignes et de colonnes d'un tableau a 2 dimensions ? Je pense a tab.GetLength par exemple ou c'est vraiment deconseiller de faire ca ? Je sais que je peux utiliser les variables nbrows et nbcol de la fonction lecture mais je n'ai pas le droit de changer son prototype.
    J'en ai besoin pour plus tard dans le projet, je m'explique vite fait :
    J'ai un fichier que je devrai transformé en tableau grace a la fonction lecture, puis je devrai initialisé une structure de ce type :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    typedef struct s_mat_char_dyn{
      char *** tab;
      int nbRows;
      int nbCol;
      int offset; // donne le nombre de colonnes avant celles des candidats
    } t_mat_char_star_dyn;
    tab designe le tableau retourné par la fonction lecture, nbRows et nbCol designent le nombre de lignes et de colonnes de ce dernier, comment je dois faire pour bien les initialiser ? Avec tab.GetLength(0) et tab.GetLength(1) ? C'est dommage parce que la fonction lecture connait deja ces variables, c'est juste qu'elle retourner q'un tableau.

    Merci bien.

  10. #10
    Membre régulier Avatar de ekieki
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Avril 2014
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 65
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Enseignant Chercheur

    Informations forums :
    Inscription : Avril 2014
    Messages : 34
    Points : 103
    Points
    103
    Par défaut
    Citation Envoyé par Gayura Voir le message
    Autre chose, en oubliant cette fonction lecture, serait-il possible de récupérer le nombre de lignes et de colonnes d'un tableau a 2 dimensions ? Je pense a tab.GetLength par exemple ou c'est vraiment deconseiller de faire ca ?
    C'est pas que c'est déconseillé, c'est juste que ça n'existe absolument pas.

Discussions similaires

  1. Réponses: 7
    Dernier message: 24/11/2011, 10h41
  2. Problème de sélection dans un tableau dynamique (gestion des erreurs)
    Par aulilou dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 01/08/2007, 16h38
  3. Réponses: 1
    Dernier message: 23/06/2006, 11h19
  4. Réponses: 9
    Dernier message: 22/06/2006, 20h06

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