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 :

problème avec scanf


Sujet :

C

  1. #1
    Membre régulier
    Inscrit en
    Novembre 2005
    Messages
    188
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 188
    Points : 106
    Points
    106
    Par défaut problème avec scanf
    Bonjour,

    J'ai un petit prblème avec ce code ci: (je vous explique plus bas comment ca marchre exactement)

    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
    int fd_write;
    int fd;
    int confirmation,inscrit;
    chat_request* sp;
     
    void sig_hand(int sig) {
      close(fd_write);
      munmap(sp,sizeof(chat_request));
      printf("mnumap effectué.\n");
      exit(0);
    }
     
    void sig_sp(int sig) {
      printf("Signal SIGUSR2 recu du serveur.\n");
    }
     
    void sig_confirm(int sig) {
      int res;
      confirmation = 1;
      /* printf("Le serveur vous confirme votre participation.\n"); */
    }
     
    int main(int argc, char** argv) {
      int n;
     
      confirmation = 0;
     
      chat_request requete;
     
      sigset_t sig_proc;
      struct sigaction action;
     
      action.sa_mask = sig_proc;
      action.sa_flags = 0;
      action.sa_handler = sig_hand;
      sigaction(SIGINT,&action,0);
     
      action.sa_handler = sig_confirm;
      sigaction(SIGUSR1,&action,0);
     
      action.sa_handler = sig_sp;
      sigaction(SIGUSR2,&action,0);
     
      /* On masque SIGUSR2 */
      sigemptyset(&sig_proc);
      sigaddset(&sig_proc,SIGUSR2);
      sigprocmask(SIG_SETMASK,&sig_proc,NULL);
     
      /* Ouvrir le segment monshm, ouverture en lecture */
      if ((fd = shm_open("monshm",O_RDONLY,0700)) == -1) {
        perror("shm_open");
      }
      printf("Segment partagé ouvert en lecture.\n");
     
      /* Etablir la projection du segment de memoire partagée */
      if ((sp = mmap(NULL,sizeof(chat_request), PROT_READ, MAP_SHARED , fd , 0)) == MAP_FAILED){
        perror("mmap");
        exit(1);
      }
     
      if ((fd_write = open("tube1",O_WRONLY)) == -1) {
        perror("open");
        exit(1);
      }
      printf("Ouverture du tube nommé tube1 en ecriture.\n");
     
      while (1) {
     
        /* Ecrit l'uid du processus courant dans le chat_request */
        requete.sender_uid = getuid();
     
        /* Ecrit le pid du processus courant dans le chat_request */
        requete.sender_pid = getpid();
     
        /* Ecrit la chaine tapé par l'utilisateur dans le chat_request*/
     
        printf("Taper un texte:\n");
     
        scanf("%s",requete.msg);
        printf("scanf: %s\n",requete.msg);
     
        /* Ecriture de la chaine contenue dans buf dans le tube nommé */
        if ((n = write(fd_write,&requete,sizeof(chat_request))) == -1) {
          perror("write");
          exit(1);
        }
      } 
      return 0;
    -----------------------------------------------------------------------------------

    J'ai un client qui ouvre un segment de mémoire partagé préalablement crée par le serveur. Il ouvre ensuite un tube en ecriture.
    Il place les données à envoyer dans chaque champ de requete qui est un struct chat_request (c pas important de savoir ce qu'il y a dedans).
    Il demande à l'utilisateur de taper un texte, et ce texte sera lui aussi rajouté dans le champ de la structure à envoyer.

    Il envoie ce struct, avec write, par un tube nommé qiu sera receptionné coté serveur (serveur que j'ai pas copié sur le foum.
    Le serveur regardera un champ de la structure pour savoir si le client lui a bien envoyé "join" (pour se joindre).
    - Si c'est pas join, le serveur zappe et voila (et il se remet en attente de qque chose dans le tube avec un read, car j'ai aussi une boucle infinie coté serveur).

    - Si c'est "join", il rajoute le pid du client (qu'il aura grace a un des chams de la strcture qu'il a recu) dans un tableau.
    Il envoie après cela un signal SIGUSR1 de confirmation au client avec kill, comme quoi celui-ci est bien enregistré.

    Quand le client recoit ce signal, il execute sig_confirm(int sig).

    Voici le pb:

    Quand le client tape n'importe quoi, tout est nikel, et il m'affiche, le scanf que la personne à taper (pq j'ai rajouté ca après le scanf du client: printf("scanf: %s\n",requete.msg).

    Quand le client tape par contre join, il m'afiche deux fois ma ligne scanf, comme si on avait tapé deux textes.

    Or normalement, si je ne tape qu'un seul texte, le scanf, dooit resté bloquant en attendant un second texte.

    J'ai testé de ne pas envoyer de signal de confimation du serveur au client, et là nikel: un seul affichage scanf...
    C'est comme l'arrivée d'un signal, arrivait à débloquer un scanf qui attend du texte et un retour chariot.....:-(

    Qu'en pensez-vous?

    Merci
    A+

  2. #2
    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 724
    Points
    5 724
    Par défaut
    Un problème du buffer stdin ?

    je n'ai pas tout lu mais les symptomes sont que tu as deux appels à scanf succesif et que le deuxieme est pas réalisé ?
    " Dis ce que tu veux qui insulte mon honneur car mon silence sera la réponse au mesquin.
    Je ne manque pas de réponse mais : il ne convient pas aux lions de répondre aux chiens ! " [Ash-Shafi'i ]

  3. #3
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    Et l'utilisation de scanf est déconseillé!

  4. #4
    Membre régulier
    Inscrit en
    Novembre 2005
    Messages
    188
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 188
    Points : 106
    Points
    106
    Par défaut re
    Un problème du buffer stdin ?
    je n'ai pas tout lu mais les symptomes sont que tu as deux appels à scanf succesif et que le deuxieme est pas réalisé ?
    En fait, le truc, c'est que si je tape "join" du coté client, même si le serveur envoie un signal au client, il ne devrait effectuer qu'un seul scanf, vu que je n'ai tapé qu'un truc, mais il m'en execute 2 avec le même texte...(et sans ce signal envoyé, il a le bon comprtement, cad il ne fait qu'un seul scanf....)

    Et l'utilisation de scanf est déconseillé!
    Ca fait pareil avec:
    fgets (requete.msg,sizeof(char)*1024, stdin); et ca m'oblige en plus à prendre en compte le saut de ligne lol.

    Merci
    A+

  5. #5
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    Teste le retour de scanf, je parierais sur un 0 ou un EOF alors... Si c'est le cas, il ne faudrait pas envoyer le message...

    fgets (requete.msg,sizeof(char)*1024, stdin); et ca m'oblige en plus à prendre en compte le saut de ligne lol.
    Je te conseille de quand même garder fgets et d'enlever le '\n'...

    Jc

  6. #6
    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 724
    Points
    5 724
    Par défaut
    Vide le buffer stdin avant chaque scanf
    " Dis ce que tu veux qui insulte mon honneur car mon silence sera la réponse au mesquin.
    Je ne manque pas de réponse mais : il ne convient pas aux lions de répondre aux chiens ! " [Ash-Shafi'i ]

  7. #7
    Membre régulier
    Inscrit en
    Novembre 2005
    Messages
    188
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 188
    Points : 106
    Points
    106
    Par défaut re
    Vide le buffer stdin avant chaque scanf
    cad en faisant un fflush?

    Merci
    A+

  8. #8
    Membre régulier
    Inscrit en
    Novembre 2005
    Messages
    188
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 188
    Points : 106
    Points
    106
    Par défaut re
    Re,

    j'ai essayé avec un fflush(stdin) avant le fgets, mais ca foire quand meme il fait tjs deux fgets consécutifs :-(.

    Merci
    A+

  9. #9
    Rédacteur

    Avatar de gege2061
    Femme Profil pro
    Administrateur de base de données
    Inscrit en
    Juin 2004
    Messages
    5 840
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Juin 2004
    Messages : 5 840
    Points : 11 625
    Points
    11 625
    Par défaut Re: re
    Citation Envoyé par thierry_b
    j'ai essayé avec un fflush(stdin) avant le fgets, mais ca foire quand meme il fait tjs deux fgets consécutifs :-(.
    Arf trop tard
    Comment vider le buffer clavier ?

  10. #10
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    EDITION: Lorsque tu fais un scanf ou un fgets, il faut toujours tester le retour. Es-tu sûr que tu testes le retour de fgets?

  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 Re: re
    Citation Envoyé par thierry_b
    Vide le buffer stdin avant chaque scanf
    cad en faisant un fflush?
    Non. fflush() n'est défini que sur les flux sortants.
    Pas de Wi-Fi à la maison : CPL

Discussions similaires

  1. Problème avec scanf
    Par OLman135 dans le forum Débuter
    Réponses: 1
    Dernier message: 31/10/2008, 14h55
  2. Problème avec "SCANF"
    Par condor666 dans le forum Débuter
    Réponses: 2
    Dernier message: 28/03/2008, 11h20
  3. Problème avec scanf("%s",str)
    Par mathieumadrid dans le forum C
    Réponses: 4
    Dernier message: 18/12/2006, 16h47
  4. problème avec scanf
    Par mimina dans le forum C
    Réponses: 27
    Dernier message: 13/11/2006, 19h30
  5. problème avec scanf
    Par troumad dans le forum C
    Réponses: 30
    Dernier message: 20/11/2005, 15h21

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