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 :

Taille d'un tableau


Sujet :

C

  1. #1
    Membre éclairé

    Profil pro
    Inscrit en
    Mai 2002
    Messages
    641
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 641
    Par défaut Taille d'un tableau
    Bonjour,

    Je souhaite utiliser la fonction str_split proposée ici. Comment connaître la taille du tableau de chaînes créés afin de le parcourir ?

  2. #2
    Invité(e)
    Invité(e)
    Par défaut
    Bonjour,

    Il faut parcourir le tableau pour en connaitre la taille :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    size_t size = 0;
    char **result = str_split(......);
    if(result != NULL) {
        while(result[size] != NULL) {
            ++size;
        }
        printf("la taille du tableau est %d\n", size);
    } else {
        printf("la fonction str_split a échoué\n");
    }

  3. #3
    Membre éclairé

    Profil pro
    Inscrit en
    Mai 2002
    Messages
    641
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 641
    Par défaut
    Merci.

  4. #4
    Membre éclairé

    Profil pro
    Inscrit en
    Mai 2002
    Messages
    641
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 641
    Par défaut
    Je souhaiterais passer le tableau précédemment obtenu (appelé fields) en paramètre à une fonction :
    void addProfileLine(char fields[], profile profiles[], int profilescount);

    Dans cette fonction je veux remplir la structure profile à partir de fields[1], fields[2]...

    Cette syntaxe provoque des warnings à la compilation :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    "add_profiles.c", line 120: warning: argument #1 is incompatible with prototype:
            prototype: pointer to char : "add_profiles.h", line 10
            argument : pointer to pointer to char
    L. 120, c.-à-d. lors de l'appel à la fonction :
    addProfileLine(fields, profiles, profilescount);

    J'ai également des warnings dans la fonction elle-même :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    "add_profiles.c", line 202: warning: improper pointer/integer combination: arg #1
    "add_profiles.c", line 204: warning: improper pointer/integer combination: op "="
    "add_profiles.c", line 206: warning: improper pointer/integer combination: op "="
    "add_profiles.c", line 208: warning: improper pointer/integer combination: op "="
    "add_profiles.c", line 210: warning: improper pointer/integer combination: op "="
    Lorsque j'essaie de récupérer les valeurs de fields[0], fields[1], etc. pour remplir ma structure.

  5. #5
    Invité(e)
    Invité(e)
    Par défaut
    Tu peux poster le code qui crée ce problème ?

    EDIT : ton compilateur dit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    "add_profiles.c", line 120: warning: argument #1 is incompatible with prototype:
            prototype: pointer to char : "add_profiles.h", line 10
            argument : pointer to pointer to char
    Cela veut dire que tu passe à la fonction un tableau de chaine à la place d'une chaine seule. (tu donnes un char ** à la place d'un char *)

  6. #6
    Membre éclairé

    Profil pro
    Inscrit en
    Mai 2002
    Messages
    641
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 641
    Par défaut
    fields est un tableau de chaîne retourné par str_split.

    Quel doit-être le prototype de la fonction addProfile ? Ceci peut-il fonctionner ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    void addProfileLine(char **fields, profile profiles[], int profilescount) {
    char tmp[100];
    strcpy(tmp, fields[0]);
    //...
    }

  7. #7
    Invité(e)
    Invité(e)
    Par défaut
    Ceci peut-il fonctionner ?
    Oui
    Quel doit-être le prototype de la fonction addProfile ?
    Ça dépend de ce que tu veux faire faire à ta fonction...

  8. #8
    Membre éclairé

    Profil pro
    Inscrit en
    Mai 2002
    Messages
    641
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 641
    Par défaut
    Désormais j'ai un coredump Bus Error lorsque j'essaie d'accéder au tableau profiles, après l'avoir rempli avec la fonction addProfile...

    La fonction est la suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    void addProfile(char *fields[], profile profiles[], int profilescount) {
    	profiles = (profile*)realloc (profiles, (profilescount + 1) * sizeof (profile));
    	if (NULL == profiles) {
    		fprintf (stderr, "Mémoire insuffisante.\n");
    		free (profiles);
    		exit (EXIT_FAILURE);
    	}
    	/* profile_id */
    	profiles[profilescount].profile_id = fields[1];
     
    	//...
    }
    Elle est appelée dans une boucle :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    addProfileLine(fields, profiles, profilescount);
    ++profilescount;

  9. #9
    Invité(e)
    Invité(e)
    Par défaut
    Montre voir comment tu accèdes aux données.

    Sinon, il faut voir que la fonction str_split ne fait pas d'allocation mémoire, donc écrire quelque chose comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    profiles[profilescount].profile_id = fields[1];
    est risqué : tu gardes l'adresse mémoire où est stocké ta chaine, mais à la modification de la chaine à découper passée à str_split, cette adresse devient invalide...

  10. #10
    Membre éclairé

    Profil pro
    Inscrit en
    Mai 2002
    Messages
    641
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 641
    Par défaut
    Citation Envoyé par mabu Voir le message
    Montre voir comment tu accèdes aux données
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    int i = 0;
    for(i=0;i<profilescount;i++) {
            printf("Ligne %d, profile_id %d.\n", profilescount, profiles[i].profile_id);
    }
    profiles est un tableau de structures.
    Pour le deuxième point j'utiliserai strcpy.

  11. #11
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    2 remarques...

    Il est toujours très nettement plus aisé en C de se servir des pointeurs que de tableaux lorsqu'ils sont passés en paramètres...

    • Quand tu écris :

      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      void addProfile(char *fields[], profile profiles[], int profilescount)
      ce serait plus clair (pour toi comme pour un relecteur éventuel) de l'écrire comme :

      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      void addProfile(char **fields, profile **profiles, int profilescount)
      Car ici on note bien que profiles (qui va être réalloué) est un pointeur qui doit ressortir modifié de la fonction...

      Ce que l'écriture profiles[] ne fait pas, étant (relativement) équivalente à *profiles.


    • Enfin, on copie une chaîne avec strcpy, sinon on copie juste le pointeur..

      Donc dans :

      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      	profiles[profilescount].profile_id = fields[1];

      tu ne copies que le pointeur et pas la chaîne...


  12. #12
    Expert confirmé

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Par défaut
    J'ajouterai qu'il faut se souvenir que la valeur d'une variable changée dans une fonction ne verra pas sa valeur changée dans la fonction appelante.

    Donc, réalloué profiles avec :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    void addProfile(char *fields[], profile profiles[], int profilescount)
    comme prototype est une erreur si tu veux avoir le nouveau pointeur après la réallocation et la fonction.

    Le prototype de souviron34 fonctionne si on ajoute les changements dans la fonction.

    Jc

  13. #13
    Membre éclairé

    Profil pro
    Inscrit en
    Mai 2002
    Messages
    641
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 641
    Par défaut
    Citation Envoyé par fearyourself Voir le message
    Le prototype de souviron34 fonctionne si on ajoute les changements dans la fonction.

    Jc
    Il faut modifier la fonction, en particulier la ré-assignations de profiles :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    profiles = (profile*)realloc (profiles, (profilescount + 1) * sizeof (profile));
    me donne une erreur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    assignment type mismatch
    Mais je ne sais pas trop quelle est la bonne syntaxe ici.
    J'ai essayé la syntaxe suivante, sans succès :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    **profiles = (profile**)realloc (profiles, (profilescount + 1) * sizeof (profile));
    Sinon, je copie bien mes chaînes avec strcpy.

  14. #14
    Expert confirmé

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Par défaut
    Si t'as du mal avec cette solution, fait simplement :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    profile *addProfile (char **fields, profile *profiles, int profilescount)
    et retourne ton tableau une fois agrandi.

    Jc

  15. #15
    Membre éclairé

    Profil pro
    Inscrit en
    Mai 2002
    Messages
    641
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 641
    Par défaut
    Le code suivant provoque un coredump :
    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
     
    void addProfile(char *fields[], profile **profiles, int profilescount) {
    	profiles = (profile**)realloc (profiles, (profilescount + 1) * sizeof (profile));
    	if (NULL == profiles) {
    		fprintf (stderr, "Mémoire insuffisante.\n");
    		free (profiles);
    		exit (EXIT_FAILURE);
    	}
    	/* profile_id */
    	profiles[profilescount]->profile_id = string2int(fields[1]);
    }
     
    char **fields = NULL;
    size_t size = 0;	
    profile **profiles;
    int profilescount = 0;
     
    while (fgets(line, LINE_SIZE, fp) != NULL) {
    	fields = str_split(line, ";");
    	if (fields != NULL) {
    		/* Calcul de la taille du tableau */
    		while(fields[size] != NULL) {
    			++size;
    		}
    		if ( PROFILE_FLD_NBR != size ) {
    			printf("Nombre de champs incorrect : %d (%d attendu).\n", size, PROFILE_FLD_NBR);
    			return EXIT_FAILURE;
    		}
    		addProfile(fields, profiles, profilescount);
    		++profilescount;
    	}
    }

  16. #16
    Invité(e)
    Invité(e)
    Par défaut
    J'aurai plus vu quelque chose comme :

    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
    char **fields = NULL;
    size_t size = 0;	
    profile *profiles = NULL;
    int profilescount = 0;
     
    while (fgets(line, LINE_SIZE, fp) != NULL) {
    	fields = str_split(line, ";");
    	if (fields != NULL) {
    		/* Calcul de la taille du tableau */
    		while(fields[size] != NULL) {
    			++size;
    		}
    		if ( PROFILE_FLD_NBR != size ) {
    			printf("Nombre de champs incorrect : %d (%d attendu).\n", size, PROFILE_FLD_NBR);
    			return EXIT_FAILURE;
    		}
    		addProfile(fields, &profiles, profilescount);
    		++profilescount;
    	}
    }
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    void addProfile(char *fields[], profile **profiles, int profilescount) {
    	*profiles = (profile*)realloc (*profiles, (profilescount + 1) * sizeof (profile));
    	if (NULL == profiles) {
    		fprintf (stderr, "Mémoire insuffisante.\n");
    		free (profiles);
    		exit (EXIT_FAILURE);
    	}
    	/* profile_id */
    	profiles[profilescount]->profile_id = string2int(fields[1]);
    }
    Car dans la première version, tu tentais de ré-allouer une zone mémoire indéfinie.

  17. #17
    Membre éclairé

    Profil pro
    Inscrit en
    Mai 2002
    Messages
    641
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 641
    Par défaut
    J'ai corrigé comme indiqué mais cela ne fait pas disparaître le coredump qui se produit lors du :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    profiles[profilescount]->profile_id = string2int(fields[1]);

  18. #18
    Invité(e)
    Invité(e)
    Par défaut
    Citation Envoyé par Neuromancien2 Voir le message
    J'ai corrigé comme indiqué mais cela ne fait pas disparaître le coredump qui se produit lors du :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    profiles[profilescount]->profile_id = string2int(fields[1]);
    Oui, effectivement, il manque (mea culpa) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (*profiles)[profilescount]->profile_id = string2int(fields[1]);

  19. #19
    Membre éclairé

    Profil pro
    Inscrit en
    Mai 2002
    Messages
    641
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 641
    Par défaut
    Citation Envoyé par mabu Voir le message
    Oui, effectivement, il manque (mea culpa) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (*profiles)[profilescount]->profile_id = string2int(fields[1]);
    Cette syntaxe ne fonctionne pas. J'ai pensé que la bonne syntaxe serait plutôt :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (*profiles+profilescount)->profile_id = string2int(fields[1]);
    Mais j'ai toujours un Segmentation Fault(coredump).

  20. #20
    Membre éclairé

    Profil pro
    Inscrit en
    Mai 2002
    Messages
    641
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 641
    Par défaut
    C'est apparemment le realloc qui pose problème. En effet avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    profiles = (profile*) malloc(10*sizeof(profile));
    if (NULL == profiles) {
    	printf("Erreur d'allocation.\n");
    	return EXIT_FAILURE;
    }
    au début, je n'ai pas de coredump.

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

Discussions similaires

  1. [Tableau]comment connaitre la taille d'un tableau à 2 dimensions
    Par Kyti dans le forum Collection et Stream
    Réponses: 4
    Dernier message: 22/04/2005, 10h27
  2. Changer la taille d'un tableau déjà initialisé
    Par totofweb dans le forum C++
    Réponses: 2
    Dernier message: 25/07/2004, 15h55
  3. taille d'un tableau
    Par monstour dans le forum ASP
    Réponses: 3
    Dernier message: 24/06/2004, 15h16
  4. Taille maximum de tableau en Delphi
    Par yannick37 dans le forum Langage
    Réponses: 5
    Dernier message: 03/03/2004, 13h18
  5. qbasic : taille d'un tableau
    Par clood200 dans le forum Basic
    Réponses: 2
    Dernier message: 16/09/2003, 07h26

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