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 :

Connaître le nombre d'éléments différents de \0 d'un char array


Sujet :

C

  1. #1
    Futur Membre du Club
    Homme Profil pro
    .
    Inscrit en
    Avril 2014
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : .

    Informations forums :
    Inscription : Avril 2014
    Messages : 9
    Points : 6
    Points
    6
    Par défaut Connaître le nombre d'éléments différents de \0 d'un char array
    Bonjour à tous,

    J'essaie de connaître le nombre de caractères autres que '\0' d'un array de caractères rempli par l'utilisateur. L'idée est de parcourir cet array (compteur : 'i') et d'incrémenter un compteur représentant le nombre de ces éléments différents de '\0' (compteur : 'j') si et seulement si l'élément en cours est différent de '\0'.

    A priori, ça devrait fonctionner ! Mais mon programme affiche toujours une taille de 10... Je vous montre le code :

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    char chaine[10];
    scanf("Tapez une chaîne de caractères : %s", chaine); // scanf va remplir chaine de l'élément n°0 à l'élément n°[taille-1 de la saisie] et placera un '\0' juste après ce dernier élément
     
        int j = 0; // représente le nombre d'éléments != '\0'
     
        int i = 0;
        while (i < sizeof(chaine)) {
            if (chaine[i] != '\0')
                j++;
     
            i++;
        }

    Voilà.
    Je ne comprends pas du tout pourquoi ça ne marche pas. Pourriez-vous m'aider svp ? :-/

    Merci d'avance et bonne continuation

  2. #2
    Membre à l'essai
    Homme Profil pro
    Lycéen
    Inscrit en
    Octobre 2013
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Octobre 2013
    Messages : 11
    Points : 19
    Points
    19
    Par défaut
    Dans le code, il y as deux choses qui ne vont pas :

    -1ere : si la taille de ta chaîne est inférieure a 10, une fois que le '\0' est passé, on continue d'incrémenter j.
    Ce qui veut dire que si on a par exemple "salut", (5 caractère, plus 1, en tout 6) j affichera 9 (10 moins le '\0')

    -2eme : si la taille de ta chaîne est supérieure a 10, (ce qui a sûrement du se passer) on ne vera jamais le '\0', car il est plus loin dans la memoire.
    Dans ce cas là fais attention au butteroverflow qui risque de se produire.

    Bref je te conseille plutôt de faire :
    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
    char chaine[10];
    char fini = 0;
    fgets(chaine, 10, stdin);// va recuperer 10 caractère max sur le clavier
        int j = 0; // représente le nombre d'éléments != '\0'
     
        int i = 0;
        while (i < sizeof(chaine) && !fini) {
            if (chaine[i] != '\0')
            {
                j++;
            }
            else
            {
                fini = 1;
            }
     
            i++;
    }

  3. #3
    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 : 46
    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
    Sans prendre en compte ton fgets mais juste pour te montrer une autre manière de faire pour connaître manuellement (sinon tu as strlen qui le fait très bien) le nombre de caractères dans une chaîne:

    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
    #include <stdio.h>
    #include <stdlib.h>
     
    int main (void)
    {
       char chaine[30] = "Bonjour, le monde !";
       char * p = chaine;
       int len = 0;
     
       while (*p++ != '\0')
          len++;
     
       printf("Taille de la chaine: %d\n", len);
     
       return EXIT_SUCCESS;
    }
    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

  4. #4
    Futur Membre du Club
    Homme Profil pro
    .
    Inscrit en
    Avril 2014
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : .

    Informations forums :
    Inscription : Avril 2014
    Messages : 9
    Points : 6
    Points
    6
    Par défaut
    Re,

    @ymerej5312 :

    Je ne comprends pas comment tu résouds le premier problème juste en utilisant fgets :-/

    Et sinon j'ai mis à jour mon code, en remplissant mon array avec 10 '\0'. Ca devrait corriger le premier problème. Maintenant, ça me renvoie toujours une taille de 0 si j'utilise scanf. Pourquoi ?

    Par contre si j'utilise fgets, pas de problème, ça marche... C'est bizarre.

    Voici le nouveau code (rien n'a changé à part le remplissage du tableau) :
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
        char chaine[10] = {'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0'};
     
        scanf("Tapez une chaîne de caractères : %s", chaine);
     
        int j = 0;
        int i = 0;
     
        while (i < sizeof(chaine)) {
            if (chaine[i] != '\0')
                j++;
     
            i++;
        }



    @Franck.H :
    Oh, c'est sympa comme astuce ça ! Merci !

  5. #5
    Futur Membre du Club
    Homme Profil pro
    .
    Inscrit en
    Avril 2014
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : .

    Informations forums :
    Inscription : Avril 2014
    Messages : 9
    Points : 6
    Points
    6
    Par défaut
    Wouuups, ça y est, j'ai trouvé le truc qui n'allait pas.

    Je pensais que le premier paramètre de scanf, ici "Tapez blabla %s", permettait de renseigner le texte de la question. Mais visiblement, c'est une sorte de regex. Excusez-moi... !

    Merci à vous deux !

  6. #6
    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 : 46
    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
    Citation Envoyé par Nohak_ Voir le message
    Par contre si j'utilise fgets, pas de problème, ça marche... C'est bizarre.
    De toutes manières, il vaut mieux utiliser fgets qui est plus sécuritaire et si tu n'as pas besoin de formatage spécifique de la chaîne.

    Citation Envoyé par Nohak_ Voir le message
    @Franck.H :
    Oh, c'est sympa comme astuce ça ! Merci !
    De rien
    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

  7. #7
    Futur Membre du Club
    Homme Profil pro
    .
    Inscrit en
    Avril 2014
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : .

    Informations forums :
    Inscription : Avril 2014
    Messages : 9
    Points : 6
    Points
    6
    Par défaut
    Alors j'ai juste une toute petite dernière question... :-3

    Lorsque j'écris : char test[10]; , test contiendra 10 valeurs aléatoires de la RAM non ? (et dont les cases-mémoires sont contiguës) Ou bien test contiendra 10 valeurs vides ou bien 10 valeurs égales à '\0' ? Je suis certain à 90% que ma première proposition est la bonne

    Oh, et puis une dernière question pour la route ! Comment remplir tous les éléments d'un array avec une seule valeur ? Parce que bon, pour un tableau de 10 éléments je fais : {'a', 'a','a' jusqu'à 10} , mais pour un tableau de 12 000 éléments, ça va être un peu chaud. Bien sûr je pourrais utiliser un for, mais bon... Y a pas un moyen plus efficace ? J'ai entendu parler de cette technique : char t[10] = {'a'}; mais cela remplit-il vraiment tout t avec 'a', ou bien juste le premier élément ?...

    Merci d'avance !

  8. #8
    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 : 46
    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
    Citation Envoyé par Nohak_ Voir le message
    Lorsque j'écris : char test[10]; , test contiendra 10 valeurs aléatoires de la RAM non ? (et dont les cases-mémoires sont contiguës) Ou bien test contiendra 10 valeurs vides ou bien 10 valeurs égales à '\0' ? Je suis certain à 90% que ma première proposition est la bonne
    Le tableau aura une valeur indéterminée mais je pense que cela peut dépendre de l'implémentation (de l'OS) mais ça reste à vérifier au niveau de la norme.

    Citation Envoyé par Nohak_ Voir le message
    Oh, et puis une dernière question pour la route ! Comment remplir tous les éléments d'un array avec une seule valeur ? Parce que bon, pour un tableau de 10 éléments je fais : {'a', 'a','a' jusqu'à 10} , mais pour un tableau de 12 000 éléments, ça va être un peu chaud. Bien sûr je pourrais utiliser un for, mais bon... Y a pas un moyen plus efficace ? J'ai entendu parler de cette technique : char t[10] = {'a'}; mais cela remplit-il vraiment tout t avec 'a', ou bien juste le premier élément ?...
    Le mieux est d'utiliser memset:
    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    int main (void)
    {
       char chaine[10];
     
       memset(chaine, 'a', 9);
       chaine [9] = '\0';
     
       printf("%s\n", chaine);
     
       return EXIT_SUCCESS;
    }
    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

  9. #9
    Futur Membre du Club
    Homme Profil pro
    .
    Inscrit en
    Avril 2014
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : .

    Informations forums :
    Inscription : Avril 2014
    Messages : 9
    Points : 6
    Points
    6
    Par défaut
    Ok, merci, je me renseignerai dessus !

    Bon en fait j'ai une autre question (mais c'est vraiment la dernière...). Le mot stdin représente l'interface d'entrée standard (la console). Mais... c'est quoi ? C'est un keyword du C ? C'est une variable appartenant à un header de la lib standard ? En tout cas ce n'est pas une fonction... De même, quand on utilise SDL, on doit écrire notamment : SDL_Init(SDL_INIT_VIDEO);. SDL_Init est une fonction. Mais qu'en est-il de SDL_INIT_VIDEO ?

    Enfin voilà, ça me paraît bizarre.

  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 : 46
    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
    Pour ce qui est de stdin, tout comme stdout et stderr, ce sont des pointeurs sur FILE, voir: http://manpagesfr.free.fr/man/man3/stdin.3.html

    Pour ce qui est de SDL_INIT_VIDEO, c'est une constante tout simplement.
    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

  11. #11
    Futur Membre du Club
    Homme Profil pro
    .
    Inscrit en
    Avril 2014
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : .

    Informations forums :
    Inscription : Avril 2014
    Messages : 9
    Points : 6
    Points
    6
    Par défaut
    Oui, mais ces pointeurs et ces constantes sont contenues dans des librairies ? On peut les retrouver dans les headers de ces lib non ?

  12. #12
    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 : 46
    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
    Citation Envoyé par Nohak_ Voir le message
    Oui, mais ces pointeurs et ces constantes sont contenues dans des librairies ? On peut les retrouver dans les headers de ces lib non ?
    Bin concernant FILE, c'est une structure contenue dans stdio.h:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    typedef struct _iobuf
    {
    	char*	_ptr;
    	int	_cnt;
    	char*	_base;
    	int	_flag;
    	int	_file;
    	int	_charbuf;
    	int	_bufsiz;
    	char*	_tmpfname;
    } FILE;
    Si tu lis la description sur le lien que je t'ai donné plus haut je pense que tu l'aurais trouvé de toi-même. Pour ce qui est de la constante de la SDL bin tu la trouve dans SDL.h tout simplement.
    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

  13. #13
    Futur Membre du Club
    Homme Profil pro
    .
    Inscrit en
    Avril 2014
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : .

    Informations forums :
    Inscription : Avril 2014
    Messages : 9
    Points : 6
    Points
    6
    Par défaut
    Ok, super, merci !
    Donc c'est ben ce que je pensais. Encore merci

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

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

    Informations forums :
    Inscription : Février 2006
    Messages : 12 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Nohak_ Voir le message
    Lorsque j'écris : char test[10]; , test contiendra 10 valeurs aléatoires de la RAM non ? (et dont les cases-mémoires sont contiguës) Ou bien test contiendra 10 valeurs vides ou bien 10 valeurs égales à '\0' ? Je suis certain à 90% que ma première proposition est la bonne
    Bonjour

    Une variable locale (à un bloc) est initialisée avec une valeur aléatoire sauf si elle est mise en "static" dans ce cas elle est initialisée à 0.
    Une variable globale est initialisée à 0.
    Et donc ceci s'applique aussi aux tableaux. Et le terme "valeur vide" ne veut absolument rien dire (rien qu'en réfléchissant tu comprendras pourquoi).

    Citation Envoyé par Nohak_ Voir le message
    Oh, et puis une dernière question pour la route ! Comment remplir tous les éléments d'un array avec une seule valeur ? Parce que bon, pour un tableau de 10 éléments je fais : {'a', 'a','a' jusqu'à 10} , mais pour un tableau de 12 000 éléments, ça va être un peu chaud. Bien sûr je pourrais utiliser un for, mais bon... Y a pas un moyen plus efficace ?
    Oui, utiliser memset() mais faut pas te faire d'illusion, memset() contient rien de plus qu'un for !!!
    Citation Envoyé par Nohak_ Voir le message
    J'ai entendu parler de cette technique : char t[10] = {'a'}; mais cela remplit-il vraiment tout t avec 'a', ou bien juste le premier élément ?...
    Juste le premier. Les autres sont initialisés à 0.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  15. #15
    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 : 46
    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
    Citation Envoyé par Sve@r Voir le message
    Oui, utiliser memset() mais faut pas te faire d'illusion, memset() contient rien de plus qu'un for !!!
    Oui beaucoup de fonctions de la bibliothèque standard ne tiennent pas sur grand chose, tu peux voir une implémentation possible sur un de mes anciens tutoriels: http://franckh.developpez.com/articl...ge=page_memset
    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

  16. #16
    Membre éclairé
    Inscrit en
    Juillet 2012
    Messages
    231
    Détails du profil
    Informations forums :
    Inscription : Juillet 2012
    Messages : 231
    Points : 870
    Points
    870
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Oui, utiliser memset() mais faut pas te faire d'illusion, memset() contient rien de plus qu'un for !!!
    C'est en général un peu plus optimisé que ça (par exemple dans la glibc), mais parfois c'est vraiment une simple boucle en effet (dans les BSD souvent).

  17. #17
    Membre éprouvé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2014
    Messages
    345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2014
    Messages : 345
    Points : 1 211
    Points
    1 211
    Par défaut
    Citation Envoyé par ymerej5312 Voir le message
    Dans ce cas là fais attention au butteroverflow qui risque de se produire.

    Sinon tu peux utiliser la fonction butterset qui va remplir ton buffer de beurre ...

  18. #18
    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 : 46
    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
    Citation Envoyé par the Hound Voir le message

    Sinon tu peux utiliser la fonction butterset qui va remplir ton buffer de beurre ...
    J'avais pas remarqué la coquille
    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

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

Discussions similaires

  1. [XL-2010] Connaître le nombre d'éléments d'un tableau
    Par Harry Covair dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 12/09/2013, 13h34
  2. Réponses: 2
    Dernier message: 24/05/2011, 09h32
  3. Connaître le nombre d'éléments d'un tableau
    Par gege2061 dans le forum Télécharger
    Réponses: 0
    Dernier message: 30/11/2010, 16h39
  4. Réponses: 2
    Dernier message: 28/04/2006, 13h28
  5. UNION de deux SELECT avec nombre d'arguments différents
    Par orus8 dans le forum Langage SQL
    Réponses: 2
    Dernier message: 16/07/2004, 14h32

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