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 :

'0' == '\0' ?


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Avatar de exe2bin
    Profil pro
    Passionné de programmation
    Inscrit en
    Mars 2009
    Messages
    537
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Passionné de programmation

    Informations forums :
    Inscription : Mars 2009
    Messages : 537
    Billets dans le blog
    3
    Par défaut '0' == '\0' ?
    Bonjour à tous ,
    je voudrais savoir si le fait de remplir une chaîne de caractère par des '0' empêche la fonction printf()
    d'afficher la chaîne entière et l'oblige à n'afficher qu'un seul "0" ,prenant les autres pour des fins de chaîne ('\0') ?

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    Billets dans le blog
    4
    Par défaut
    Quelle est la question ?
    '0' n'a rien à voir avec \0, le premier est le caractère 0, le nombre 0, le second est le caractère null, de fin de chaîne.
    printf comme la majorité des fonctions C de traitement de chaînes de caractères s'arrêtera au premier \0.
    Initialiser une chaîne avec des \0 peut être une bonne pratique et éviter des déboires.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  3. #3
    Membre éclairé
    Avatar de exe2bin
    Profil pro
    Passionné de programmation
    Inscrit en
    Mars 2009
    Messages
    537
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Passionné de programmation

    Informations forums :
    Inscription : Mars 2009
    Messages : 537
    Billets dans le blog
    3
    Par défaut
    Ok ,
    J'ai une routine de codage de chaîne de caractères composée de '0' et '1' :
    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
     
    char *codage(char *clairBin) {
        int i,j,cle,binSize,pas;
        char *codon,*codeBin,*codeLimit;
        //
        binSize = strlen(clairBin);
        cle = (binSize/8);
        pas = cle-1;
        //
        codon = malloc(cle+1);
        codon[cle] = '\0';
        //
        codeBin = malloc(binSize+1);
        codeBin[binSize] = '\0';
        for(i=0;i<8;i++) {
            j = 0;
            strncpy(codon,clairBin+(i*cle),cle);
            printf("codon %d : %s\n",i,codon);
            codeLimit = codeBin+((i*cle)+pas);
            //printf("codeLimit = %u\n",codeLimit);
            while(j < cle) {
                switch (codon[j]) {
                    case '0':
                        //printf("%c",codon[j]);
                        codeBin[(i*cle)+j] = codon[j];
                        j++;
                        if(j < cle) {
                            //printf("-%c",codon[j]);
                            *codeLimit = codon[j];
                            codeLimit--;
                            j++;
                        }
                        break;
     
                    default:// '1'
                        //printf("%c",codon[j]);
                        codeBin[(i*cle)+j] = codon[j];
                        j++;
                        break;
                }
            }
        }
        printf("\ncodeBin : %s\n",codeBin);
        return codeBin;
    }
    Le problème c'est que la variable codeBin ne semble contenir qu'un unique caractère alors qu"elle "devrait" être aussi
    longue que la chaîne paramètre de la fonction .
    Est-ce que quelqu'un voit quelque chose car je ne vois plus rien !!!

  4. #4
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 816
    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 816
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par exe2bin Voir le message
    Est-ce que qq voit qq chose car je ne voit plus rien !!!
    Me semble déjà que "cle" devrait être plus longue de 1 à cause de la perte dans la division (ben oui, si la chaine d'origine est longue par exemple de 4, alors "cle" vaudra 0 ce qui n'est pas tiptop pour une zone mémoire à réserver). En fait, la bonne formule devrait être cle=(binSize-1)/8 + 1.
    De plus tes strncpy(codon,clairBin+(i*cle),cle)) réécrasent à chaque fois le contenu de "codon". Tu ne pensais pas plutôt à strncat() ???
    Quoi qu'il arrive, fais attention car ces fonctions arrêtent la copie soit quand la fin de la chaine à copier est atteinte ; soit quand elles ont copié "n" caractères. Mais dans ce dernier cas, elles ne positionnent pas de '\0'.

    Citation Envoyé par exe2bin Voir le message
    je voudrais savoir si le fait de remplir une chaîne de caractère par des '0' empêche la fonction printf() d'afficher la chaîne entière et l'oblige à n'afficher qu'un seul "0" ,prenant les autres pour des fins de chaîne ('\0') ?
    printf() n'affiche jamais de '\0' (ni plusieurs, ni même un seul). De plus, elle ne peut pas prendre "les autres" pour des fins de chaine puisqu'elle s'arrête au premier (elle ne verra donc pas "les autres"). Et même pire, si elle continuait après le premier '\0' rencontré pour regarder ce qu'il y a après, comment saurait-elle alors où s'arrêter ???
    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]

  5. #5
    Membre éclairé
    Avatar de exe2bin
    Profil pro
    Passionné de programmation
    Inscrit en
    Mars 2009
    Messages
    537
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Passionné de programmation

    Informations forums :
    Inscription : Mars 2009
    Messages : 537
    Billets dans le blog
    3
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Bonjour

    Me semble déjà que "cle" devrait être plus longue de 1 à cause de la perte dans la division (ben oui, si la chaine d'origine est longue par exemple de 4, alors "cle" vaudra 0 ce qui n'est pas tiptop pour une zone mémoire à réserver). En fait, la bonne formule devrait être cle=(binSize-1)/8 + 1.
    De plus tes strncpy(codon,clairBin+(i*cle),cle)) réécrasent à chaque fois le contenu de "codon". Tu ne pensais pas plutôt à strncat() ???
    Quoi qu'il arrive, fais attention car ces fonctions arrêtent la copie soit quand la fin de la chaine à copier est atteinte ; soit quand elles ont copié "n" caractères. Mais dans ce dernier cas, elles ne positionnent pas de '\0'.
    Exact ,mais le truc (pour l'instant ) c'est que aucunes chaîne parvenant à la fonction n'est plus petite que 24 caractères et qq soient leur nombre
    ils sont toujours multiples de 8.
    codon est effectivement écrasé à chaque tour de boucle et cela est bien car son contenu n'a plus d'importance une fois traité.
    Citation Envoyé par Sve@r Voir le message
    printf() n'affiche jamais de '\0' (ni plusieurs, ni même un seul). De plus, elle ne peut pas prendre "les autres" pour des fins de chaine puisqu'elle s'arrête au premier (elle ne verra donc pas "les autres"). Et même pire, si elle continuait après le premier '\0' rencontré pour regarder ce qu'il y a après, comment saurait-elle alors où s'arrêter ???
    As-tu essayé la fonction et si oui peux tu dire pourquoi la chaîne finale contient un seul caractère ?

  6. #6
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 816
    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 816
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par exe2bin Voir le message
    et qq soient leur nombre ils sont toujours multiples de 8.
    Ok. Ta formule fonctionne donc pour ce cas particulier. Mais la mienne fonctionne pour tous les cas...

    Citation Envoyé par exe2bin Voir le message
    codon est effectivement écrasé à chaque tour de boucle et cela est bien car son contenu n'a plus d'importance une fois traité.
    Ok

    Citation Envoyé par exe2bin Voir le message
    As-tu essayé la fonction et si oui peux tu dire pourquoi la chaîne finale contient un seul caractère ?
    Je te sens un peu aggressif. Pourtant j'ai fait des efforts (et je pensais que tu me connaissais un peu là dessus). J'ai effectivement essayé mais ne sachant pas à l'origine tes entrées à 24c, j'avais mis "toto". Et après avoir remplacé ta formule par la mienne ; et remplacé strncpy() par strncat(), j'ai vu "codon" se remplir au fur et à mesure et "codeBin" contenait bien "toto". Donc pour moi c'était bon. C'est pas ma faute si ça ne fonctionne pas.

    Effectivement en mettant "000011110000111100001111" (soit 24 caractères) je n'en ai plus qu'un seul en final. Mais en mettant "abcdefghijklmnopqrstuvwx" ça me ressort tout correctement. Le souci vient donc de la chaine entrée et de son traitement. Et en mettant "111111111111111111111111" ça me ressort aussi tout correctement.
    Accessoirement, pour plus de précision, "codeBin" ne contient pas qu'un seul caractère. Il en contient plein. Si tu n'en vois qu'un seul, c'est parce que le second vaut '\0' et que printf() s'arrête alors à cette valeur.

    Je fais donc quelques essais (à ta place). Avec 8 ou 16 "0" ça va mais avec 24 ou 32 ça ne va plus. Là, je commence à penser au comportement indéterminé surtout avec ton j++ qui se fait tantôt une fois, tantôt deux fois ; et ce codelimit-- lui aussi un peu erratique. Mais c'est certainement de ma faute si je ne comprends pas ce que tu fais car j'ai qu'à lire les nombreux commentaires de ton algo...

    Je laisse ton printf("codon %d : %s\n",i,codon) mais je rajoute printf("i=%d, codon[%d]=%d\n",i, j, codon[j]) juste avant le switch() et printf("i=%d, j=%d, codeBin[%d]=%d\n",i, j, i*cle+j, codeBin[i*cle+j]) juste après et voici ce que ça me sort à l'écran (pour une chaine contenant 24 "0")
    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
    moi@virtualux:/tmp$ make a
    cc     a.c   -o a
    moi@virtualux:/tmp$ ./a
    cle=3
    codon 0 : 000
    i=0, codon[0]=48
    i=0, j=2, codeBin[2]=48
    i=0, codon[2]=48
    i=0, j=3, codeBin[3]=0
    codon 1 : 000
    i=1, codon[0]=48
    i=1, j=2, codeBin[5]=48
    i=1, codon[2]=48
    i=1, j=3, codeBin[6]=0
    codon 2 : 000
    i=2, codon[0]=48
    i=2, j=2, codeBin[8]=48
    i=2, codon[2]=48
    i=2, j=3, codeBin[9]=0
    codon 3 : 000
    i=3, codon[0]=48
    i=3, j=2, codeBin[11]=48
    i=3, codon[2]=48
    i=3, j=3, codeBin[12]=0
    ...etc etc jusqu'à i=7 et j=24...
    codeBin : 0
    x=0
    Donc que remarque-t-on ? Au premier tour de boucle tu remplis codeBin[2]. Mais que contient codeBin[0] et codeBin[1] ??? Et ensuite à chaque tour de boucle chaque codeBin[x] (avec x multiple de 3) vaut 0. Or la valeur 0 (qu'on peut aussi représenter par le caractère '\0') est la valeur qui indique "fin de chaine". Donc toute fonction qui lira ta chaine s'arrêtera au premier 0 (ou '\0') rencontré. Et qu'il se trouve que déjà ce 0 (ou '\0') est positionné au 3° caractère (donc quoi qu'il y ait après printf() n'en lira jamais plus de 2) mais qu'en plus comme tu n'as rien indiqué concernant les deux premiers, il se trouve que cette zone mémoire (qui contient alors n'importe quoi) contient alors ici spécialement (pasdbol) un caractère '\0' et au final donc tu n'en vois plus qu'un seul...

    Citation Envoyé par exe2bin Voir le message
    Est-ce que qq voit qq chose car je ne voit plus rien !!!
    Je pense que tu devrais revoir intégralement ton algo. Ou nous expliquer ce que tu cherches à faire. Surtout avec ce codeLimit qui vient en plus interférer dans le truc...
    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]

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

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