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 :

Comparer chaînes de caractères


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2013
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

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

    Informations forums :
    Inscription : Février 2013
    Messages : 6
    Par défaut Comparer chaînes de caractères
    Bonjour. Alors j'ai besoin de votre aide. J'ai un mini projet à rendre et je suis bloqué quand je compare deux chaînes de caractères. Je vous envoie mon code et dites-moi ce qui est faux, svp

    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
    void update()
    { int i;
        int t,call1,call2,r1=0,r2=0;
        char choix2;
        char n[30],p[30];
     
          gotoxy(30,7);
          printf("que voulez vous modifier?\n");
          gotoxy(30,8);
          printf("1.le nom et le numero\n");
          gotoxy(30,9);
          printf("2.la date\n");
          gotoxy(30,11);
          printf(" choix : ");
          choix2=getch();
     
          switch (choix2)
            { case '1':
            clrscr();
            gotoxy(30,5);
            printf("veuillez saisir un nom");
            fgets (n,30,stdin);
            gotoxy(30,6);
            printf("veuillez saisir un prenom");
            fgets (p,30,stdin);
     
            for(i=0;i<count;i++)
            {r1=strcmp(R[i].avec.nom,n);
             r2=strcmp(R[i].avec.prenom,p);
            if(r1==0 && r2==0)
    {
             clrscr();
            gotoxy(30,5);
            printf("nom trouvé saisir le nouveau nom:");
            fflush(stdin);
            scanf("%s",&R[i].avec.nom);
            fflush(stdin);
            gotoxy(30,6);
            printf("veuillez saisir le prenom:");
            fflush(stdin);
            scanf("%s",&R[i].avec.prenom);
            gotoxy(30,7);
            printf("numero");
            scanf("%d", &E[i].num);
                }
            else {printf("error");}
                }
     
            break;
     
            case '2':
     
            clrscr();
            gotoxy(31,5);
            printf("saisir une date:\n");
            gotoxy(40,6);
            printf("le jour :");
            gotoxy(49,6);
            scanf("%d",&call1);
            gotoxy(40,7);
            printf("le mois :");
            gotoxy(49,7);
            scanf("%d",&call2);
     
    t=search_rdv(call1,call2);
            if(t==1)
        {   printf("saisir une nouvelle date:\n");
            gotoxy(40,6);
            printf("le jour :");
            gotoxy(49,6);
            scanf("%d",&call1);
            gotoxy(40,7);
            printf("le mois :");
            gotoxy(49,7);
            scanf("%d",&call2);
     
            for(i=0;i<count2;i++)
            {clrscr();
     
            R[trv[i]].date.jour=call1;R[trv[i]].date.mois=call2;
    gotoxy(40,12);
            system("PAUSE");}
     
        }
     
            break;
     
        }
     
    }
    Là, le truc, c'est une fonction qui recherche un nom pour le modifier après le R[i].avec.nom . Ça vient des structs, etc… Là, même si j'ai le même nom, on ne me redemande pas d'insérer le nouveau nom et ça revient au menu principal, mais ça se compile quand même.

  2. #2
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 839
    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 839
    Billets dans le blog
    1
    Par défaut
    Bonjour

    Sans connaitre le détail de R1.avec.nom c'est pas facile mais à mon avis c'est la faute au fgets(n, 30, stdin). Réfléchis une seconde à ce que tu fais à ce moment là: tu tapes le nom puis tu appuies sur <return>. Ben tout ce qui a été tapé est alors recopié dans le nom; y compris le <return> qui devient un '\n'.

    Solution: supprimer ce '\n'. Rajoutes l'instruction suivante juste en dessous if ((x=strchr(p, '\n')) != NULL) *p='\0'; (x défini comme un char*) et à mon avis ça fonctionnera...
    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]

  3. #3
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2013
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

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

    Informations forums :
    Inscription : Février 2013
    Messages : 6
    Par défaut
    Finalement j'ai changer mes scanf en fgets(R[count].sujet,sizeof(R[count].sujet),stdin); (exemple pour la saisie du sujet) et sa a marché (sur internet j'ai lu que c'était un blem d'overflow quand y'a des case vide) c'est cool que sa marche mais j'aimerais bien comprendre exactement pourquoi pour ne pas retomber sur la même erreur ^^

  4. #4
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 839
    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 839
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par benmovitchy Voir le message
    Finalement j'ai changer mes scanf en fgets(R[count].sujet,sizeof(R[count].sujet),stdin); (exemple pour la saisie du sujet) et sa a marché
    Mouais. Ton code d'origine contient déjà des fgets()...???

    Ceci dit, attention toutefois à l'utilisation de sizeof()...

    Voici un exemple qui fonctionne
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    int main()
    {
        char nom[30];
        fgets(nom, sizeof(nom), stdin);
    }

    Mais ça ne fonctionnera plus si on déporte la saisie dans une fonction dédiée...
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    int main()
    {
        char nom[30];
        saisie(nom);
    }
     
    void saisie(char *data)
    {
        fgets(data, sizeof(data), stdin);
    }

    La raison c'est que dans la fonction, le tableau "nom" a été envoyé et reçu sous forme de pointeur (adresse du premier élément). Or le sizeof() d'un pointeur renvoie la taille du pointeur c'est à dire la taille d'une adresse c'est à dire 4 (en 32 bits) ou 8 (en 64 bits).

    Citation Envoyé par benmovitchy Voir le message
    (sur internet j'ai lu que c'était un blem d'overflow quand y'a des case vide)
    Rien compris surtout que fgets() reçoit le nb de caractères max à saisir donc il ne devrait jamais y avoir d'overflow avec cette fonction (pour ça qu'on la préfère à gets())...

    Citation Envoyé par benmovitchy Voir le message
    mais j'aimerais bien comprendre exactement pourquoi pour ne pas retomber sur la même erreur ^^
    Il te faut analyser avec attention chaque caractère de la zone saisie, et chaque caractère de la zone à comparer. Avec un printf() dans une boucle ça peut le faire.

    Accessoirement il ne faut pas flusher stdin. Déjà c'est pas implémenté de partout, quand c'est implémenté le comportement n'est pas garanti et quand on sait gérer son clavier (notemment en supprimant les '\n' résiduels) on se rend compte que c'est inutile (c'est d'ailleurs pour ça que l'implémentation n'est pas assurée)...
    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 du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2013
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

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

    Informations forums :
    Inscription : Février 2013
    Messages : 6
    Par défaut
    Wow slow down je ne fait que commencer ^^' c'est un projet pour premiere année universitaire j'ai cherché sur google et j'ai trouvée que fgets allais resourdre mon blem et ce que j'ai compris dans ton message c'est les \n qui me causent probleme si je les enleve et et change tout les fgets et les rend des scanf sa redeviendrais normal? le truc ce qu'on m'a expliqué aussi c'est que fflush(stdin) est utilisé pour le probleme de mémoire ou ché pas quoi

  6. #6
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2013
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

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

    Informations forums :
    Inscription : Février 2013
    Messages : 6
    Par défaut
    J'ajoute aussi que j'ai utilisé fgets dans ma fonction ajout de donné (le nom et le prenom) et je l'ai utilisé dans ma fonction modifier (update) lors de la saisie du nom et prénom a chercher pour le modifier

  7. #7
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 839
    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 839
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par benmovitchy Voir le message
    et j'ai trouvée que fgets allais resourdre mon blem et ce que j'ai compris dans ton message c'est les \n qui me causent probleme si je les enleve et et change tout les fgets et les rend des scanf sa redeviendrais normal?
    Chaque outil a une fonction précise et surtout aucun outil n'est magique. Un outil X sera parfait dans une situation mais catastrophique dans une autre.

    Le gros problème de scanf() c'est qu'il attend une entrée "formatée". Or ce que tape un utilisateur est tout sauf formaté (il peut lui arriver de taper n'importe quoi). Mais même s'il tape tout correctement, scanf pose problème du fait que tout ce qui est tapé n'est pas forcément traité.

    Exemple
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    int age;
    char nom[50];
    printf("Entrez votre age :\n");
    scanf("%d", &age);
    printf("Entrez votre nom:\n");
    scanf("%s", nom);
    Avec ce code, même en mettant la meilleure volonté du monde, tu ne pourras jamais entrer ton nom. Parce que quand tu entres ton age, tu valides par '\n'. Et le '\n' n'étant pas numérique n'est pas consommé par scanf("%d") et reste dans le clavier. Et au scanf suivant, ce '\n' résiduel est alors récupéré et va dans le nom. Ce qui a amené certains profs débiles à dire aux élèves de rajouter un fflush(stdin) alors qu'il suffisait juste de réfléchir et rajouter un simple fgetc(stdin) sous le premier scanf pour libérer ce '\n'.

    Mais même un fgetc() ne règle pas tous les soucis. Si l'utilisateur tape "toto" au premier scanf, tout le programme part en vrille. Idem s'il entre 500 caractères à la saisie du nom qui ne peut en contenir que 50. Et comment faire pour saisir "pierre édouard" (avec un espace) ?

    Ce qui amène alors à passer par fgets(). L'avantage de fgets, c'est qu'il limite la saisie (on ne peut pas en mettre plus que ce qui est autorisé), il prend tout ce qui est tapé (même les espaces) et comme justement il récupère tout le texte tapé quel qu'il soit (même le '\n'), le clavier est toujours clean. Ensuite on peut tranquillement traiter ce qu'il a récupéré.

    Exemple
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    char tampon[100];
    int age;
    while (1)
    {
        printf("Entrez votre age :\n");
        fgets(tampon, 100, stdin);
        if (sscanf(tampon, "%d", &age)) == 1) break;
        printf("Vous n'avez pas saisi un chiffre correct, recommencez !!!\n");
    }
    Seul danger: si l'utilisateur entre 500 caractères, les 400 qui dépassent restent dans stdin. On a alors le choix de les vider manuellement (du fgetc(stdin) en boucle) ou de laisser la boucle de saisie se dérouler et les consommer. Mais inutile de passer par fflush(stdin) qui reste non stantard et souvent non fonctionnel.

    Donc oui scanf() va te libérer le problème du '\n' mais il t'en apportera d'autres à la place. Ensuite tout dépend de la criticité de ton truc. Si tu veux taper un petit code vite fait qui durera 10mn pour tester un truc, scanf() ira parfaitement. Mais si tu veux un truc plus pérenne, alors je conseille fgets(). J'étais d'ailleurs content, quand j'ai vu ton premier code, de voir que tu utilisais fgets et pas scanf !!!
    Surtout que supprimer le '\n' c'est franchement pas la mort. A la limite tu fouts ça dans une fonction dédiée qui s'occupe de ça et tu t'embêtes plus...

    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    void saisie(char *prompt, char *data, size_t n)
    {
        char *pt;
     
        fputs(prompt, stdout);
        fgets(data, n, stdin);
        if ((pt=strchr(data, '\n')) != NULL) *pt='\0';
    }

    Et ensuite
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    char n[30],p[30];
    saisie("veuillez saisir un nom :", n, 30);
    saisie("veuillez saisir un numéro :", p, 30);

    Citation Envoyé par benmovitchy Voir le message
    le truc ce qu'on m'a expliqué aussi c'est que fflush(stdin) est utilisé pour le probleme de mémoire ou ché pas quoi
    Quand un aveugle guide un autre aveugle, tous deux tombent dans le trou !!!
    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]

Discussions similaires

  1. Parcours de chaîne pour comparer avec un caractère
    Par scofild20 dans le forum Assembleur
    Réponses: 1
    Dernier message: 11/05/2007, 18h51
  2. Comparer deux chaînes de caractère
    Par natie_49 dans le forum Langage
    Réponses: 2
    Dernier message: 28/03/2007, 11h53
  3. Comparer deux chaînes de caractères
    Par camoa dans le forum x86 16-bits
    Réponses: 2
    Dernier message: 10/12/2006, 14h30
  4. [MD5] Comparer 2 chaînes de caractères
    Par wolflinger dans le forum Langage
    Réponses: 16
    Dernier message: 26/04/2006, 14h30

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