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 :

[Débutant] Initialiser un tableau de chaine de caractères


Sujet :

C

  1. #1
    Membre habitué
    Homme Profil pro
    Inscrit en
    Octobre 2006
    Messages
    130
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Octobre 2006
    Messages : 130
    Points : 146
    Points
    146
    Par défaut [Débutant] Initialiser un tableau de chaine de caractères
    Bonjour,

    je débute sur les chaines de caractères en C, j'ai suivi la doc du site en utilisant la fonction strcpy mais cela ne fonctionne pas.

    Voici le code en question, j'essaie d'initialiser le tableau de chaines de 5 caractères nom[N][5] à 0 mais cela ne fonctionne pas

    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
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    #define N 10
     
    char nom[N][5];
    int absi[N];
    int ord[N];
     
    void initTab() //initialise les tableaux à 0
    {
      int i;
     
      for(i=0;i<N;++i)
        strcpy(nom[i][5],"0");
     
      for(i=0;i<N;++i)
      {
        absi[i]=0;
        ord[i]=0;           
      } 
    }
     
    void affiche() //affiche les tableaux
    {
      int i,j;
     
      for(i=0;i<N;++i)
        printf("%s",nom[i][5]);
      printf("\n");
     
      for(i=0;i<N;++i)
        printf("%d",absi[i]);
      printf("\n");
     
      for(i=0;i<N;++i)
        printf("%d",ord[i]);  
      printf("\n");       
    }
     
    int main()
    { 
     
      initTab();
      affiche();
     
      system("pause");
     
      return EXIT_SUCCESS;
    }
    merci pour votre aide

  2. #2
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Points : 12 462
    Points
    12 462
    Par défaut
    Salut,

    en fait tu peux les initialiser directement pendant leur déclaration comme suit:
    sinon tu peux aussi le faire de cette manière:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    for (i = 0; i < N; i++)
    {
       memset (nom[i], 0, 5);
    }

  3. #3
    Membre expérimenté
    Avatar de Gruik
    Profil pro
    Développeur Web
    Inscrit en
    Juillet 2003
    Messages
    1 566
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juillet 2003
    Messages : 1 566
    Points : 1 729
    Points
    1 729
    Par défaut
    Salux

    Tu veux initialiser avec un caractere "0" ou mettre des caracteres nuls (\0) dans les chaines?

    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define N 10
    
    char nom[N][5];
    int absi[N];
    int ord[N];
    
    void initTab() //initialise les tableaux à 0
    {
      int i;
         
      for(i=0;i<N;++i)
        strcpy(nom[i]/* [5] */,"0");
          
      for(i=0;i<N;++i)
      {
        absi[i]=0;
        ord[i]=0;           
      } 
    }
    
    void affiche() //affiche les tableaux
    {
      int i,j;
         
      for(i=0;i<N;++i)
        printf("%s",nom[i]/* [5] */);
      printf("\n");
          
      for(i=0;i<N;++i)
        printf("%d",absi[i]);
      printf("\n");
      
      for(i=0;i<N;++i)
        printf("%d",ord[i]);  
      printf("\n");       
    }
    
    int main()
    { 
      
      initTab();
      affiche();
      
      system("pause");
    
      return EXIT_SUCCESS;
    }

  4. #4
    Membre Expert

    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Juin 2003
    Messages
    4 506
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2003
    Messages : 4 506
    Points : 5 723
    Points
    5 723
    Par défaut
    #define N 10
    char nom[N][5];
    <...>
    strcpy(nom[i][5],"0");
    Les indices débutent à zéro nom[i][5] est hors borne le dernier élément de la ligne est à l'indice 4.

    Dans inittab et affichtab

  5. #5
    Membre habitué
    Homme Profil pro
    Inscrit en
    Octobre 2006
    Messages
    130
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Octobre 2006
    Messages : 130
    Points : 146
    Points
    146
    Par défaut
    c'est bon, j'arrive à initialiser le tableau

    maintenant je cherche à le remplir avec des valeurs rentrées au clavier
    tant que la valeur rentrée n'est pas vide il doit stocker cette valeur dans la première case libre (=0) et également stocker 2 autres valeurs dans 2 autres tableaux au même indice que dans le premier

    il doit y avoir un souci dans les boucles car il y a une boucle infinie si la chaine est et il ne remplit pas le tableau dans le cas contraire

    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
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    #define N 10
     
    char nom[N][5];
    int absi[N];
    int ord[N];
     
    void initTab() //initialise les tableaux à 0
    {
      int i;
     
      for(i=0;i<N;++i)
        strcpy(nom[i],"0");
     
      for(i=0;i<N;++i)
      {
        absi[i]=0;
        ord[i]=0;           
      } 
    }
     
    void affiche() //affiche les tableaux
    {
      int i,j;
     
      for(i=0;i<N;++i)
        printf("%s",nom[i]);
      printf("\n");
     
      for(i=0;i<N;++i)
        printf("%d",absi[i]);
      printf("\n");
     
      for(i=0;i<N;++i)
        printf("%d",ord[i]);  
      printf("\n");       
    }
     
    int lire ()
    {
      int compt=0;
      int i;
      char temp[5];
     
      for(;;)
      {
        printf("nom ?");
        scanf("%s",&temp);
     
        if(temp=="")
          break;
        else
          for(i=0;i<N;++i)
          {
            if(nom[i]=="0")
            {
              strcpy(nom[i],temp);
              printf("abs ?");
              scanf("%d",&absi[i]);
              printf("ord ?");
              scanf("%d",&absi[i]);
              compt++;
            }
          }           
        return compt;
      }       
    }
     
     
    int main()
    { 
      initTab();
     
      lire();
     
      affiche();
     
     
      system("pause");
     
      return EXIT_SUCCESS;
    }

  6. #6
    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 tomasi
    maintenant je cherche à le remplir avec des valeurs rentrées au clavier
    tant que la valeur rentrée n'est pas vide il doit stocker cette valeur dans la première case libre (=0) et également stocker 2 autres valeurs dans 2 autres tableaux au même indice que dans le premier

    il doit y avoir un souci dans les boucles car il y a une boucle infinie si la chaine est et il ne remplit pas le tableau dans le cas contraire
    Ton code corrigé et commenté. Pose des questions si tu ne comprends pas.
    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
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    #define N 10
     
    char nom[N][5];
    int absi[N];
    int ord[N];
     
    void initTab ()                 //initialise les tableaux à 0
    {
       int i;
     
       for (i = 0; i < N; ++i)
          strcpy (nom[i], "0");
     
       for (i = 0; i < N; ++i)
       {
          absi[i] = 0;
          ord[i] = 0;
       }
    }
     
    void affiche ()                 //affiche les tableaux
    {
       int i
       /* -ed- jamais utilisee...
       , j
       */
       ;
     
       for (i = 0; i < N; ++i)
          printf ("%s", nom[i]);
       printf ("\n");
     
       for (i = 0; i < N; ++i)
          printf ("%d", absi[i]);
       printf ("\n");
     
       for (i = 0; i < N; ++i)
          printf ("%d", ord[i]);
       printf ("\n");
    }
     
    int lire ()
    {
       int compt = 0;
       int i;
       char temp[5];
     
       for (;;)
       {
          printf ("nom ?");
     
          /* -ed-
             scanf("%s",&temp);
     
             pas de & pour un tableau
           */
          scanf ("%s", temp);
     
          /* -ed-
             if(temp=="")
     
             ce n'est pas comme ca que l'on compare des chaines.
             Relire le cours sur les chaines.
     
           */
          if (strcmp (temp, "") == 0)
          {
             break;
          }
          else
          {
             for (i = 0; i < N; ++i)
             {
                /* -EDIT */
                if (strcmp (nom[i], "0") == 0)
                {
                   strcpy (nom[i], temp);
                   printf ("abs ?");
     
                   scanf ("%d", &absi[i]);
     
                   printf ("ord ?");
     
                   /* -ed-
                      scanf("%d",&absi[i]);
     
                      pas le bon tableau.
                    */
                   scanf ("%d", &ord[i]);
                   compt++;
                }
             }
          }
          /* -ed-
          return compt;
     
          probablement mal place (dans la boucle ? etrange...)
          deplace a la fin...
          */
       }
          return compt;
    }
     
     
    int main ()
    {
       initTab ();
     
       lire ();
     
       affiche ();
     
       system ("pause");
     
       return EXIT_SUCCESS;
    }
    C'est bien d'utiliser des fonctions, mais tu devrais apprendre aussi à ne pas utiliser de variables globales.

    D'autre part les données sont mal organisées. Tu peux sans doute un tableau de structures.

  7. #7
    Membre habitué
    Homme Profil pro
    Inscrit en
    Octobre 2006
    Messages
    130
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Octobre 2006
    Messages : 130
    Points : 146
    Points
    146
    Par défaut
    merci pour ces corrections

    quel est le problème avec les variables globales ?

    est-il préférable de tout passer en arguments ?

    sinon à l'exécution du code j'ai toujours un souci, il ne me prend pas la valeur du nom et il ne passe pas non plus au remplissage des tableaux ord et absi

  8. #8
    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 tomasi
    quel est le problème avec les variables globales ?
    http://emmanuel-delahaye.developpez....s.htm#globales
    est-il préférable de tout passer en arguments ?
    Oui, c'est fait pour...
    sinon à l'exécution du code j'ai toujours un souci, il ne me prend pas la valeur du nom et il ne passe pas non plus au remplissage des tableaux ord et absi
    Avec quel code ?

  9. #9
    Membre expérimenté
    Avatar de Gruik
    Profil pro
    Développeur Web
    Inscrit en
    Juillet 2003
    Messages
    1 566
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juillet 2003
    Messages : 1 566
    Points : 1 729
    Points
    1 729
    Par défaut
    J'utilise souvent les globales pour des TAD, mais en static uniquement. Ca correspond un peu à des "variables de classe" privées.
    Ex d'utilité : faire un traitement particulier à la premiere utilisation du module.

  10. #10
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Points : 12 462
    Points
    12 462
    Par défaut
    En générale, si je ne peut faire autrement que d'utiliser une variable globale, je la met en privé et je créé un accesseur/modificateur mais cela est vraiment très rare que j'ai besoin de ce genre de variable.

    C'est une manière plus propre je trouve

  11. #11
    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 Gruik
    J'utilise souvent les globales pour des TAD, mais en static uniquement. Ca correspond un peu à des "variables de classe" privées.
    Ex d'utilité : faire un traitement particulier à la premiere utilisation du module.
    Argh ! A quoi ça peut bien servir ?

    TADs et globales, sont antinomiques !

  12. #12
    Membre expérimenté
    Avatar de Gruik
    Profil pro
    Développeur Web
    Inscrit en
    Juillet 2003
    Messages
    1 566
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juillet 2003
    Messages : 1 566
    Points : 1 729
    Points
    1 729
    Par défaut
    On peut imaginer que des modules aient besoin de "s'initialiser" (=> recuperer, preparer certaines resources, mais des resources internes au module), et de se "liberer". Cette initialisation pourrait se faire lorsque le premier objet du TAD est construit, et la liberation pourrait se faire à un appel explicite de liberation ( libereTesResources(); ) (ou avec atexit() ou bien un "attribut de fonction destructeur" à la gcc).

    Je sais pas, on pourrait imaginer un transformateur de texte qui aurait besoin de lire un fichier de configuration lorsqu'il s'initialise, la construction d'un objet de ce TAD dependrait de ce fichier de configuration

    D'un coté, on pourrait creer un autre TAD pour gerer ce "createur de resources"
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    struct resources_parser * rp = create_parser();
     
    struct text * my_text = parse (rp, input_text);
     
    /* ... */
     
    free_text (my_text);
    free_parser(rp);
    Mais ça serait qd meme lourd de se trimballer cet objet rp partout, d'autant qu'il n'y a pas lieu d'avoir plusieurs instances de "resources_parser"

  13. #13
    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 Gruik
    On peut imaginer que des modules aient besoin de "s'initialiser" (=> recuperer, preparer certaines resources, mais des resources internes au module), et de se "liberer". Cette initialisation pourrait se faire lorsque le premier objet du TAD est construit, et la liberation pourrait se faire à un appel explicite de liberation ( libereTesResources(); ) (ou avec atexit() ou bien un "attribut de fonction destructeur" à la gcc).
    Ah, du code de goret, OK... Je ne mange pas de ce pain là... Pourquoi pas un Garbage Collector tant que tu y es... On est en C, là, pas en C pointu qui danse la java...
    Je sais pas, on pourrait imaginer un transformateur de texte qui aurait besoin de lire un fichier de configuration lorsqu'il s'initialise, la construction d'un objet de ce TAD dependrait de ce fichier de configuration

    D'un coté, on pourrait creer un autre TAD pour gerer ce "createur de resources"
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    struct resources_parser * rp = create_parser();
     
    struct text * my_text = parse (rp, input_text);
     
    /* ... */
     
    free_text (my_text);
    free_parser(rp);
    Mais ça serait qd meme lourd de se trimballer cet objet rp partout, d'autant qu'il n'y a pas lieu d'avoir plusieurs instances de "resources_parser"
    OK, dans le cas de gestion de ressources uniques, c'est acceptable. En lecture seule, OK ? (WORM)

  14. #14
    Membre habitué
    Homme Profil pro
    Inscrit en
    Octobre 2006
    Messages
    130
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Octobre 2006
    Messages : 130
    Points : 146
    Points
    146
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    Dans le code que j'ai posté, il y reste un bug (comparaisons de chaines avec == au lieu de strcmp()).
    je ne vois pas à quel endroit...

    le code que j'ai essayé est celui posté et corrigé

    le souci que je rencontre est qu'il ne break pas quand la chaine rentrée est vide et que si elle n'est pas vide il redemande en boucle les valeurs de abs et ord au lieu de passer au point suivant (triplet nom, abs, ord)

  15. #15
    Membre habitué
    Homme Profil pro
    Inscrit en
    Octobre 2006
    Messages
    130
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Octobre 2006
    Messages : 130
    Points : 146
    Points
    146
    Par défaut
    personne n'a d'indications pour me sortir de ce mauvais pas ?

  16. #16
    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 tomasi
    je ne vois pas à quel endroit...
    J'ai corrigé le code et effacé ma remarque...
    le code que j'ai essayé est celui posté et corrigé
    le mien ?
    le souci que je rencontre est qu'il ne break pas quand la chaine rentrée est vide et que si elle n'est pas vide il redemande en boucle les valeurs de abs et ord au lieu de passer au point suivant (triplet nom, abs, ord)
    C'est possible. Tu ne sais pas corriger le code ? Ca fait un peu parti de ce métier non ? Faut se creuser la cervelle, ça va venir...

    Par exemple : Comment peut-on savoir si une chaine est vide ?
    Une fois qu'on le sait, il faut agir en conséquence...

Discussions similaires

  1. Réponses: 10
    Dernier message: 31/05/2007, 15h10
  2. tableau de chaine de caractères
    Par psgman113 dans le forum C
    Réponses: 15
    Dernier message: 22/01/2007, 18h52
  3. Pointeur, tableau et chaines de caractères.
    Par rouliane dans le forum C++
    Réponses: 8
    Dernier message: 19/12/2006, 20h27
  4. Réponses: 2
    Dernier message: 10/05/2006, 15h23
  5. [C] tableau de chaines de caractères
    Par kitsune dans le forum C
    Réponses: 18
    Dernier message: 01/04/2006, 18h18

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