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 :

Comportement boucle WHILE très étrange


Sujet :

C

  1. #1
    Membre très actif
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Février 2013
    Messages
    125
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2013
    Messages : 125
    Par défaut Comportement boucle WHILE très étrange
    Salut tout le monde voila j'ai déjà posté mon sujet sur un autre site mais je n'ai pas encore eu de réponse ( enfin si mais pers n'a de réponse a mon problème )

    voila je fait un TP du pendu qui est un des exercices proposer sur ce site et mon while ne boucle plus que sur la variable nbEssaie .

    j 'utilise une variable que j'ai appelé "boolean" qui me sert de boolean afin de décrémenter ma variable "nbEssai" si la personne n'a pas trouver le bon caractère , sauf que dés que j utilise cette variable ma seconde condition qui vérifie si les chaines de caractères sont égal ne fonctionne plus .
    la boucle devrai normalement stopper quand le nombre d’essai arrive a 0 ou que les chaines de caractères dans les deux tableaux sont identiques

    pour résume mon while ne fonctionne que si le nombre d’essai arriver a 0 et continu de boucler même si les chaines de caractères sont identiques .

    MAIS WHILE fonctionne dés que je retire cette variable "boolean" .

    Voila mon code Merci pour votre aide

    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    void MyFlush(void);
    int main()
    {
        int i ;
        int nbEssai = 10;
        int longueurchaine = 10;
        int ChaineIdentique = 1;
        int boolean = 0;
        const char motSecret[10] = "elephant";
        char motSecretcopy[10];
        char lettre;
        char chaine1[longueurchaine] , chaine2[longueurchaine];
     
        /*******************************/
        /** longueurchaine est égal a la taille de la chaine "motSecret" .*/
     
        longueurchaine = strlen(motSecret);
     
        /*******************************/
        /** création d'un tableau d'étoile égale a la longueur de la chaine motSecret .*/
     
        for (i=0; i<longueurchaine; i++)
        {
            motSecretcopy[i]='*';
        }
     
     
        /*******************************/
        printf("\n");
        printf("Bienvenue dans le Pendu\n");
     
     
     
        /*******************************/
        /** tant que le nombre d’essai est inférieur à 0 ou que la chaine de caractère est différente on boucle */
     
        while (nbEssai > 0 && ChaineIdentique!=0  )
     
        {
            printf("\nIl vous reste %d essai \n\n",nbEssai);
            printf("\nEntrer une lettre ! ");
            scanf ("%c",&lettre);
            MyFlush();
     
            boolean=0;
     
            /** boucle qui parcours le tableau */
     
            for (i=0; i<longueurchaine; i++ )
     
            {
                /** Condition qui vérifie si la lettre entrer est égal au tableau a la position "i"
                    si oui je copie la lettre entrer dans un autre tableau et je met la variable
                    "boolean a a 1 afin de ne pas décrémenter la variable "essaie"   */
     
                if (lettre == motSecret[i])
     
                {
                    motSecretcopy[i]=lettre;
                    boolean=1;
     
                }
     
            }
            /*******************************/
            /** Boucle qui affiche le tableau */
     
            for (i=0; i<longueurchaine; i++)
            {
                printf("%c",motSecretcopy[i]);
            }
     
            /** La variable " ChaineIdentique " contient la fonction strcmp qui permet de verifier si deux chaine de caractére sont identiques .*/
     
            ChaineIdentique =  strcmp(motSecret, motSecretcopy) ;
     
            /** Condition qui verifie si ma variable " boolean " est égal a 0 si oui la variable " nbEssaie " est décrémenter de 1 */
     
            if ( boolean == 0)
            {
                nbEssai--;
            }
        }
     
     
        /*******************************/
        /** Affichage du tableau  a la fin du grace a une boucle */
     
        printf("\n\n");
        printf("\n");
        for (i=0; i<longueurchaine; i++)
        {
            printf("%c",motSecretcopy[i]);
        }
     
     
        return 0;
    }
     
    /*******************************/
    /** Fonction qui permet de vider le scanf avant de le réutiliser dans une boucle afin d'éviter qui garde en mémoire un caractère */
     
    void MyFlush(void)
    {
        scanf("%*[^\n]");
        getchar();
    }

  2. #2
    Membre éprouvé
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2012
    Messages
    53
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Maroc

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2012
    Messages : 53
    Par défaut
    Salut, le problème j’espère dans strcmp, j'ai changé la méthode de comparaison, et quelques choses dans le code, tu vas voir le changement.
    le code marche bien maintenant, je vais te donner deux solutions qui marchent bien, j'ai déjà essayé
    première:
    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <conio.h>
    void MyFlush(void);
    int main()
    {
        int i ;
        int nbEssai = 10;
        int longueurchaine = 10;
        int ChaineIdentique = 0;//s'éatit 1, maintenant 0
        int boolean = 0;
        const char motSecret[10] = "pinom";
        char motSecretcopy[10] ;
        char lettre;
        char chaine1[longueurchaine] , chaine2[longueurchaine];
     
        /*******************************/
        /** longueurchaine est égal a la taille de la chaine "motSecret" .*/
     
        longueurchaine = strlen(motSecret);
     
        /*******************************/
        /** création d'un tableau d'étoile égale a la longueur de la chaine motSecret .*/
     
        for (i=0; i<longueurchaine; i++)
        {
            motSecretcopy[i]='*';
        }
     
     
        /*******************************/
        printf("\n");
        printf("Bienvenue dans le Pendu\n");
     
     
     
        /*******************************/
        /** tant que le nombre d’essai est inférieur à 0 ou que la chaine de caractère est différente on boucle */
     
        while ( nbEssai > 0 && ChaineIdentique != 1)//l'initialisation de ChaineIdentique est chnagé en haut
     
        {
            printf("\nIl vous reste %d essai \n\n",nbEssai);
            printf("\nEntrer une lettre ! ");
            scanf ("%c",&lettre);
            MyFlush();
            printf("\n\n");
            boolean=0;
     
            /** boucle qui parcours le tableau */
     
            for (i=0; i<longueurchaine; i++ )
     
            {
                /** Condition qui vérifie si la lettre entrer est égal au tableau a la position "i"
                    si oui je copie la lettre entrer dans un autre tableau et je met la variable
                    "boolean a a 1 afin de ne pas décrémenter la variable "essaie"   */
     
                if (lettre == motSecret[i])
     
                {
                    motSecretcopy[i]=lettre;
                    boolean=1;
     
                }
     
            }
     
            /*******************************/
            /** Boucle qui affiche le tableau */
     
            for (i=0; i<longueurchaine; i++)
            {
                printf("%c",motSecretcopy[i]);
            }
     
            /** La variable " ChaineIdentique " contient la fonction strcmp qui permet de verifier si deux chaine de caractére sont identiques .*/
            //ChaineIdentique =  strcmp(motSecret, motSecretcopy) ;
     
     
            //voila ce que j'ai ajouté
              ChaineIdentique = 1 ;
            for(int j = 0 ; j < longueurchaine ; j++)
            {
                    if( motSecret[j] != motSecretcopy[j] )
                    {
                     ChaineIdentique = 0 ;
                    }
            }
     
            /*if( ChaineIdentique == 1 )
            {
                    printf("\n\n____________________IDENTIQUE____________________\n\n");
                    system("pause");
                    exit(0);
            }*/
     
            //jusqu'ici
            /** Condition qui verifie si ma variable " boolean " est égal a 0 si oui la variable " nbEssaie " est décrémenter de 1 */
     
            if ( boolean == 0)
            {
                nbEssai--;
            }
        }
     
     
        /*******************************/
        /** Affichage du tableau  a la fin du grace a une boucle */
     
        printf("\n\n");
        printf("\n");
        for (i=0; i<longueurchaine; i++)
        {
            printf("%c",motSecretcopy[i]);
        }
     
     
        return 0;
    }
     
    /*******************************/
    /** Fonction qui permet de vider le scanf avant de le réutiliser dans une boucle afin d'éviter qui garde en mémoire un caractère */
     
    void MyFlush(void)
    {
        scanf("%*[^\n]");
        getchar();
    }
    la deuxième
    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <conio.h>
    void MyFlush(void);
    int main()
    {
        int i ;
        int nbEssai = 10;
        int longueurchaine = 10;
        int ChaineIdentique = 0;//s'éatit 1, maintenant 0
        int boolean = 0;
        const char motSecret[10] = "pinom";
        char motSecretcopy[10] ;
        char lettre;
        char chaine1[longueurchaine] , chaine2[longueurchaine];
     
        /*******************************/
        /** longueurchaine est égal a la taille de la chaine "motSecret" .*/
     
        longueurchaine = strlen(motSecret);
     
        /*******************************/
        /** création d'un tableau d'étoile égale a la longueur de la chaine motSecret .*/
     
        for (i=0; i<longueurchaine; i++)
        {
            motSecretcopy[i]='*';
        }
     
     
        /*******************************/
        printf("\n");
        printf("Bienvenue dans le Pendu\n");
     
     
     
        /*******************************/
        /** tant que le nombre d’essai est inférieur à 0 ou que la chaine de caractère est différente on boucle */
     
        while ( nbEssai > 0 )//&& ChaineIdentique != 1)//l'initialisation de ChaineIdentique est chnagé en haut
     
        {
            printf("\nIl vous reste %d essai \n\n",nbEssai);
            printf("\nEntrer une lettre ! ");
            scanf ("%c",&lettre);
            MyFlush();
            printf("\n\n");
            boolean=0;
     
            /** boucle qui parcours le tableau */
     
            for (i=0; i<longueurchaine; i++ )
     
            {
                /** Condition qui vérifie si la lettre entrer est égal au tableau a la position "i"
                    si oui je copie la lettre entrer dans un autre tableau et je met la variable
                    "boolean a a 1 afin de ne pas décrémenter la variable "essaie"   */
     
                if (lettre == motSecret[i])
     
                {
                    motSecretcopy[i]=lettre;
                    boolean=1;
     
                }
     
            }
     
            /*******************************/
            /** Boucle qui affiche le tableau */
     
            for (i=0; i<longueurchaine; i++)
            {
                printf("%c",motSecretcopy[i]);
            }
     
            /** La variable " ChaineIdentique " contient la fonction strcmp qui permet de verifier si deux chaine de caractére sont identiques .*/
            //ChaineIdentique =  strcmp(motSecret, motSecretcopy) ;
     
     
            //voila ce que j'ai ajouté
              ChaineIdentique = 1 ;
            for(int j = 0 ; j < longueurchaine ; j++)
            {
                    if( motSecret[j] != motSecretcopy[j] )
                    {
                     ChaineIdentique = 0 ;
                    }
            }
     
            if( ChaineIdentique == 1 )
            {
                    printf("\n\n____________________IDENTIQUE____________________\n\n");
                    system("pause");
                    exit(0);
            }
     
            //jusqu'ici
            /** Condition qui verifie si ma variable " boolean " est égal a 0 si oui la variable " nbEssaie " est décrémenter de 1 */
     
            if ( boolean == 0)
            {
                nbEssai--;
            }
        }
     
     
        /*******************************/
        /** Affichage du tableau  a la fin du grace a une boucle */
     
        printf("\n\n");
        printf("\n");
        for (i=0; i<longueurchaine; i++)
        {
            printf("%c",motSecretcopy[i]);
        }
     
     
        return 0;
    }
     
    /*******************************/
    /** Fonction qui permet de vider le scanf avant de le réutiliser dans une boucle afin d'éviter qui garde en mémoire un caractère */
     
    void MyFlush(void)
    {
        scanf("%*[^\n]");
        getchar();
    }
    j'ai juste commenté les parties différentes, et le mot secret == "pinom" pas "elephant"

  3. #3
    Membre très actif
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Février 2013
    Messages
    125
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2013
    Messages : 125
    Par défaut j'ai oublié de dire quelque chose :(
    Déjà merci beaucoup pour ton aide
    bon la première chose que j'ai faite c'est de tester ton code et .... il me dit que ton for suivant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
           ChaineIdentique = 1 ;
            for(int j = 0 ; j < longueurchaine ; j++)
            {
                    if( motSecret[j] != motSecretcopy[j] )
                    {
                     ChaineIdentique = 0 ;
                    }
            }
    est simplement allowed en mode c99 et moi je suis en c89 un truc comme ça lol

  4. #4
    Membre éprouvé
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2012
    Messages
    53
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Maroc

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2012
    Messages : 53
    Par défaut
    J'ai pas compris
    c'est quoi c89 et c99, explique bien

  5. #5
    Membre éprouvé
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2012
    Messages
    53
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Maroc

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2012
    Messages : 53
    Par défaut
    Ok oK, c'est la normalisation, je sais pas les différences

  6. #6
    Membre très actif
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Février 2013
    Messages
    125
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2013
    Messages : 125
    Par défaut c'est bon
    en fait tu sait la ligne suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
            for(int j = 0 ; j < longueurchaine ; j++)
    n'est pas reconnu en c89 voila ce que l on dit sur un site

    " Le langage C existe en plusieurs versions.
    Une version récente, appelée le C99, autorise la création de tableaux à taille dynamique, c'est-à-dire de tableaux dont la taille est définie par une variable

    Or cela n'est pas forcément reconnu par tous les compilateurs, certains planteront sur la seconde ligne. Le langage C que je vous enseigne depuis le début (appelé le C89) n'autorise pas ce genre de choses. Nous considèrerons donc que faire cela est interdit. "

    Donc en fait ton code fonctionne A MERVEILLEEEEE lol j'ai juste retirer le int dans le for et déclarer le int j; en debut de programme , car le mode c89 n'autorise pas la déclaration d'une variable dans le for ( contrairement au c99 ou au JAVA )

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     for( j = 0 ; j < longueurchaine ; j++)
    je vois que tu a retirer la fonction STRCMP pour en créer une toi même qui fait exactement la même chose .
    sait tu pourquoi la fonction STRCMP fonctionne quand je ne déclare pas la variable boolean qui décrémente? je trouve ça étrange comme comportement .

    de plus je vois de nouvelle chose grâce a ton code comme le exit ou le system pause .

  7. #7
    Membre très actif
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Février 2013
    Messages
    125
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2013
    Messages : 125
    Par défaut j'ai fait quelque modification de ton code :)
    voila j'ai modifier ceci

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    /**************************************/
      /** ton code  while ( nbEssai > 0 ) */
     
         /**************************************/
      /** MON CODE  */
        while ( nbEssai > 0 && ChaineIdentique!=1)
    et retirer ceci .

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
      /**************************************/
      /** ton code  */
     
    //        if( ChaineIdentique == 1 )
    //        {
    //                printf("\n\n____________________IDENTIQUE____________________\n\n");
    //                system("pause");
    //                exit(0);
    //        }

    et garder ton for qui boucle pour vérifier le tableau et si le tableau est égal ta variable chaineIdentique est égal a 1

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
         ChaineIdentique = 1 ;
            for(j = 0 ; j < longueurchaine ; j++)
            {
                    if( motSecret[j] != motSecretcopy[j] )
                    {
                     ChaineIdentique = 0 ;
                    }
            }

  8. #8
    Membre expérimenté Avatar de moins1
    Homme Profil pro
    Autre
    Inscrit en
    Février 2013
    Messages
    85
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Autre
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Février 2013
    Messages : 85
    Par défaut
    Tu devrais faire en sorte que motSecretcopy soit une "vrai" chaîne de caractère avec le '\0' à la fin quoi. Ça te faciliterais la tâche un peu. Pour l'affichage tu pourrais utiliser printf() ou puts(). Pour vérifier si le mot est trouvé tu pourrais utiliser strchr() ou strcmp().

    Par exemple pour savoir si le mot est trouvé avec strchr():
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    if((strchr(motSecretcopy, '*') == NULL)
         // Mot est trouvé, y'a plus de '*'
    else
        // Pas trouvé.
    Sinon pour placer les '*' y'a memset();
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    memset(motSecretcopy, '*', longueurchaine);
    Enfin c'est juste de petites idées comme ça.


  9. #9
    Membre éprouvé
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2012
    Messages
    53
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Maroc

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2012
    Messages : 53
    Par défaut
    J'ai la même idée, sauf que, c'est mieux d'utiliser une allocation dynamique pour motSecretcopy, et la déclaration de motSecret soit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char *motSecret = "ta chaine";
    parce que une variable de type char de longueur plus que son contenue peut poser un problème de comparaison ou autres.

  10. #10
    Membre très actif
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Février 2013
    Messages
    125
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2013
    Messages : 125
    Par défaut
    oui oui j'y ai pensé mais ça pose des problèmes en c89 l'allocation dynamique

  11. #11
    Membre Expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Par défaut
    L'allocation dynamique pose des problèmes en C89 ? Comment ça ? Tu peux expliquer ?

  12. #12
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 498
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 498
    Billets dans le blog
    1
    Par défaut
    voila ce que l on dit sur un autre site

    " Le langage C existe en plusieurs versions.
    Une version récente, appelée le C99, autorise la création de tableaux à taille dynamique, c'est-à-dire de tableaux dont la taille est définie par une variable

    Or cela n'est pas forcément reconnu par tous les compilateurs, certains planteront sur la seconde ligne. Le langage C que je vous enseigne depuis le début (appelé le C89) n'autorise pas ce genre de choses. Nous considèrerons donc que faire cela est interdit. "
    Moi je dis qu'on devrait commencer à coder en C99 sauf si on utilise uniquement Visual Studio (Microsoft n'est en effet pas du tout motivé pour utiliser ce standard). Il y a plein de choses intéressantes en C99 et le fait de pouvoir mixer déclarations de variables et codes est sans doute la principale (avec les commentaires au format /// )

    L'allocation dynamique pose des problèmes en C89 ? Comment ça ? Tu peux expliquer ?


    J'ai la même idée, sauf que, c'est mieux d'utiliser une allocation dynamique pour motSecretcopy, et la déclaration de motSecret soit :
    Code :Sélectionner tout - Visualiser dans une fenêtre à part
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char *motSecret = "ta chaine";
    parce que une variable de type char de longueur plus que son contenue peut poser un problème de comparaison ou autres.
    Personnellement, je dirais qu'il faut déclarer de cette façon :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    const char *motSecret = "ta chaine";
    C'est la manière classique de déclarer une chaîne constante. En effet, le compilateur voit une chaine "ta chaine" et la place en mémoire constante. Si le pointeur n'est pas défini comme pointant sur un type constant, il serait possible de tenter de le modifier et de se chopper une erreur de segmentation ; en revanche, avec le mot-clé const, le compilateur émettra une erreur. On pourrait même écrire const char * const motSecret = "ta chaine"; pour éviter de faire plus loin dans le code motSecret = "autre chaine";. Voir la FAQ : http://c.developpez.com/faq/?page=po...OINTEURS_const

    Le problème avec const char motSecret[10] = "pinom"; n'est pas un problème de taille lors d'une comparaison avec strlen(). En effet, quelques soient le mode de stockage de la chaîne, cette fonction s'arrête quand elle rencontre un \0 et non quand elle arrive au bout de l'espace de stockage (bout qu'elle ne peut pas connaitre). Le "soucis" est qu'on réserve 10 en dur alors que la chaîne ne consomme que 6 caractères (\0 compté). Il y a donc 4 caractères "perdus" car réservés en mémoire mais non utilisés.

    A noter l'importance différence du rôle de "pinom" dans les 2 lignes suivantes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    const char motSecret[10] = "pinom";
    const char *motSecret = "pinom";
    1) C'est une chaine pour initialiser le contenu de motSecret mais n'est pas placé à un endroit spécifique en mémoire. Elle est juste copié dans la variable. Voir : http://c.developpez.com/faq/?page=strings#STRINGS_init
    2) C'est une chaine qui sera placé quelque part en mémoire et le pointeur motSecret contiendra l'adresse de cet emplacement. Voir : http://c.developpez.com/faq/?page=st...RINGS_pointeur

  13. #13
    Modérateur
    Avatar de gangsoleil
    Homme Profil pro
    Manager / Cyber Sécurité
    Inscrit en
    Mai 2004
    Messages
    10 150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Manager / Cyber Sécurité

    Informations forums :
    Inscription : Mai 2004
    Messages : 10 150
    Par défaut
    Bonjour,

    Tes chaines ne sont simplement pas identiques, car tu n'initialises pas la fin de la chaine de motSecretcopy.

    Voici un affichage des deux chaines :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    [elephant]
    [e*e*****ã@]
    Donc ta comparaison n'est pas bonne, car strcmp ne verifie pas si les N premiers caracteres sont les memes, mais si les deux chaines sont les memes.
    "La route est longue, mais le chemin est libre" -- https://framasoft.org/
    Les règles du forum

  14. #14
    Membre expérimenté Avatar de moins1
    Homme Profil pro
    Autre
    Inscrit en
    Février 2013
    Messages
    85
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Autre
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Février 2013
    Messages : 85
    Par défaut
    Citation Envoyé par b-med Voir le message
    J'ai la même idée, sauf que, c'est mieux d'utiliser une allocation dynamique pour motSecretcopy, et la déclaration de motSecret soit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char *motSecret = "ta chaine";
    parce que une variable de type char de longueur plus que son contenue peut poser un problème de comparaison ou autres.
    J'comprend pas trop pourquoi tu dis ça. Utiliser strchr(), memset() ou toutes autres fonctions de string.h et l'allocation dynamique pose pas de problème.

    D'ailleurs plus loin dans le tuto le PO va devoir lire le mot à trouver dans un fichier et va très probablement utiliser ces fonctions. Par le fait même y'aura plus de chaîne constante ou pas.


  15. #15
    Membre éprouvé
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2012
    Messages
    53
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Maroc

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2012
    Messages : 53
    Par défaut
    Citation Envoyé par moins1 Voir le message
    J'comprend pas trop pourquoi tu dis ça. Utiliser strchr(), memset() ou toutes autres fonctions de string.h et l'allocation dynamique pose pas de problème.

    D'ailleurs plus loin dans le tuto le PO va devoir lire le mot à trouver dans un fichier et va très probablement utiliser ces fonctions. Par le fait même y'aura plus de chaîne constante ou pas.

    Salut, j'ai dit pas des problèmes avec strchr(), memset() et string.h,
    pour exemple, la variable motSecretcopy ne contient pas le "\0" juste après le mot "pinom", parce que son initialisation:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    for (i=0; i<longueurchaine; i++)
        {
            motSecretcopy[i]='*';
        }
    le "\0" et placé à la fin, donc c'est mieux que la longueur de la variable soit identique à son contenue,
    comme a dit Bktero, c'est la meilleur déclaration
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    const char *motSecret = "ta chaine";

  16. #16
    Modérateur
    Avatar de gangsoleil
    Homme Profil pro
    Manager / Cyber Sécurité
    Inscrit en
    Mai 2004
    Messages
    10 150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Manager / Cyber Sécurité

    Informations forums :
    Inscription : Mai 2004
    Messages : 10 150
    Par défaut
    Dans ce cas precis, il n'est pas necessaire, pour cette etape, d'utiliser une chaine plus longue que le mot (au '\0' pres).

    Neanmoins, lorsque tu dis :
    une variable de type char de longueur plus que son contenue peut poser un problème de comparaison ou autres.
    je ne suis pas d'accord : il suffit de l'initialiser correctement, et de s'en servir correctement.

    Ce n'est pas plus dangeureux que pleins d'autres choses, il suffit de savoir ce que l'on fait. Si on ne sait pas ce qu'on fait, il faut apprendre.
    "La route est longue, mais le chemin est libre" -- https://framasoft.org/
    Les règles du forum

  17. #17
    Membre très actif
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Février 2013
    Messages
    125
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2013
    Messages : 125
    Par défaut allocation dynamique
    en fait sur le forum quelqu'un ma dit de ne jamais déclarer une variable comme ceci ex : char motSecretCopy[longueurChaine]; car ceci ne serai pas reconnu en c89. Maintenant pourquoi coder en c89 et pas en c99 directement je ne sait pas mais peut etre pour apprendre les bases? aucune idée sinon
    Merci pour votre aide j'essaye encore de comprendre votre discution mdrr

  18. #18
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 498
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 498
    Billets dans le blog
    1
    Par défaut
    C'est vrai. En C89, la taille d'un tableau (indiquée entre []) doit être une constante. L'écriture que tu montres est la définition d'un variable length array, type de tableau introduit en C99. Pour utiliser une telle écriture, il faut donc travailler en C99 et non en C89.

    Beaucoup de gens disent que le C99 ne doit pas être utilisé. Je ne fais personnellement pas partie de ces gens. Comme évoqué dans un précédent message, je pense qu'il y a des fonctionnalités intéressantes en C99 et j'ai envie de les utiliser. En fait, certains compilateurs ne supportent pas (tout) C99 et c'est la raison invoquée pour ne pas l'utiliser. Cette section Wikipédia contient une liste de compilateurs* implémentant C99 (je ne suis pas capable de juger de sa véracité) : http://en.wikipedia.org/wiki/C99#Implementations. A l'exception notable de Microsoft Visual Studio, le support est quand même bien complet pour les compilateurs cités. Il me semble donc assez facile de faire du code bien supporté par la plupart des compilateurs.
    * : j'utilise au travail le compilateur ARMCC de Keil / ARM et il supporte aussi un mode C99.

    Apprendre C89 et non C99 n'a à mon avis aucun intérêt particulier, pédagogiquement parlant.

  19. #19
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    Je suis partisan de la même approche, je recommande toute fois d'apprendre les différences entre les deux. Le cas échéant, tu pourra modifier un code C99 ne compilant pas en C89.

Discussions similaires

  1. Comportement etrange boucle while
    Par JackJnr dans le forum Débuter
    Réponses: 5
    Dernier message: 28/01/2014, 13h33
  2. DateTime comportement très étrange
    Par pjmorce dans le forum C#
    Réponses: 7
    Dernier message: 25/11/2013, 13h25
  3. [XL-2010] Comportement très étrange
    Par jpclabaux dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 02/02/2012, 01h19
  4. Comportement très étrange pour CString
    Par squale32 dans le forum Visual C++
    Réponses: 15
    Dernier message: 15/05/2008, 12h55
  5. [débutant]Documentation? boucle "while"? Session?
    Par o151181 dans le forum Servlets/JSP
    Réponses: 2
    Dernier message: 19/01/2004, 16h20

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