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 :

Utilisation de read [Débutant(e)]


Sujet :

C

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2012
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2012
    Messages : 28
    Points : 9
    Points
    9
    Par défaut Utilisation de read
    Bonjour à tous !

    J'ai le code suivant :

    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
    int fd;
    unsigned char message_Lu[TAILLE_MESSAGE];
     
    //read(fd, message_Lu, TAILLE_MESSAGE);
     
    /*Variables temporaires*/
    char s;
    int i=0, error;
     
    while ((error=read(fd, &s, 1)) > 0)
    {
       message_Lu[i++] = s;
       if(s == '\n')
       {
         message_Lu[i] = '\0';
         break;
       }
    }
     
    if (error<0)
    {
      perror("File descriptor invalide");
      exit(EXIT_FAILURE);
    }
    Où fd est déjà définit (c'est un descripteur de tube). Je veux donc lire ce qui se trouve dans mon tube. Deux solutions :

    - La première qui est commentée (ligne 4) marche parfaitement, j'arrive à lire ce qui se trouve dans mon tube.
    - La deuxième que je veux utiliser (reste du programme ligne 6-24) ne fonctionne pas et me renvoit l'erreur "Bad File descriptor".

    Je me dis donc que ma boucle merde quelque part, je force donc mon fd à 0 (pour lire le clavier). Stupeur, ce que je tape au clavier est correctement lu par ma boucle.

    Si l'erreur ne vient ni du fd (puisqu'il fonctionne dans la 1ere solution) ni de la boucle (test avec fd à 0), d'où provient-elle ?


    Celui qui résoudra ce problème aura ma gratitude éternelle !

  2. #2
    Membre émérite
    Homme Profil pro
    Inscrit en
    Décembre 2011
    Messages
    1 186
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2011
    Messages : 1 186
    Points : 2 502
    Points
    2 502
    Par défaut
    Bonsoir,

    fd est déjà définit (c'est un descripteur de tube)
    Juste pour confirmer, la ligne 1 int fd; n'existe pas en réalité dans le code.
    ou bien fb est initialisé entre cette ligne et le read.

    Dans ce cas c'est peut être l'initialisation de fb le problème.

    et me renvoit l'erreur "Bad File descriptor".
    read() < 0 ne veut pas forcément dire Bad File Descriptor.
    Il peut y avoir des problèmes de droits.

    Pour avoir plus de détail sur l'erreur, regarde du côté de la variable globale errno
    et la fonction perror() de la librairie errno.h
    pour être sûr de l'erreur.

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2012
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2012
    Messages : 28
    Points : 9
    Points
    9
    Par défaut
    Merci pour ces pistes BlueMonkey.

    Effectivement ça peut porter à confusion mais le int fd était juste là dire que fd a le bon type (d'ailleurs il vaut 6 quand je fais un printf dessus). Donc il n'existe pas dans mon code.

    Non effectivement ce n'est pas toujours "Bad File Descriptor" car pendant ma phase de debugage où je tentais autre chose j'ai aussi obtenu un "Bad adress"

    Par contre je ne sais pas comment m'y prendre pour avoir plus de détail sur l'erreur, tu peux m'en dire plus ?

  4. #4
    Membre émérite
    Homme Profil pro
    Inscrit en
    Décembre 2011
    Messages
    1 186
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2011
    Messages : 1 186
    Points : 2 502
    Points
    2 502
    Par défaut
    Il suffit d'afficher la chaîne correspondant au code errno avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    printf("Erreur n° %d : %s",errno, strerror(errno));
    Sinon pour avoir l'historique des erreurs systèmes.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #include <errno.h>
    #include <stdio.h>
     
    extern char *_sys_errlist[];
     
    int main()
    {
       int i = 0;
     
       while(_sys_errlist[i++]) printf("%s\n", _sys_errlist[i]);
       return 0;
    }

  5. #5
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2012
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2012
    Messages : 28
    Points : 9
    Points
    9
    Par défaut
    Je viens de me renseigner, j'ai pas mon code sous la main demain je ferai mes tests, aussi avec ce que tu viens de me dire.

    Par contre j'ai oublié quelque chose qui pourrait bien résoudre mon problème...

    N'ayant pas fais une compilation -Wall il se peut qu'il m'affiche un warning qui est source de l'erreur. J'ai oublié errno.h .

    Tu penses que c'est de là que vient le problème ? J'en aurai le coeur net demain.

  6. #6
    Membre émérite
    Homme Profil pro
    Inscrit en
    Décembre 2011
    Messages
    1 186
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2011
    Messages : 1 186
    Points : 2 502
    Points
    2 502
    Par défaut
    Bonjour,

    J'ai oublié errno.h. [...] Tu penses que c'est de là que vient le problème ?
    Je ne sais pas si ça résoudra tous les problèmes. Par contre tu ne pourras pas utiliser
    errno et strerror sans cette librairie.

  7. #7
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2012
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2012
    Messages : 28
    Points : 9
    Points
    9
    Par défaut
    L'erreur ne pouvait pas être ça sinon il m'aurait gueulé dessus en l'utilisant, j'y ai pensé après coup .


    Donc la ligne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    printf("Erreur n° %d : %s",errno, strerror(errno));
    Me donne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Erreur n°9 : Bad File Descriptor
    Mais alors :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #include <errno.h>
    #include <stdio.h>
     
    extern char *_sys_errlist[];
     
    int main()
    {
       int i = 0;
     
       while(_sys_errlist[i++]) printf("%s\n", _sys_errlist[i]);
       return 0;
    }
    Me donne un nombre important d'erreur système :

    Operation not permitted
    No such file or directory
    No such process
    Interrupted system call
    Input/output error
    No such device or address
    Argument list too long
    Exec format error
    Bad file descriptor
    No child processes
    Resource temporarily unavailable
    Cannot allocate memory
    Permission denied
    Bad address
    Block device required
    Device or resource busy
    File exists
    Invalid cross-device link
    No such device
    Not a directory
    Is a directory
    Invalid argument
    Too many open files in system
    Too many open files
    Inappropriate ioctl for device
    Text file busy
    File too large
    No space left on device
    Illegal seek
    Read-only file system
    Too many links
    Broken pipe
    Numerical argument out of domain
    Numerical result out of range
    Resource deadlock avoided
    File name too long
    No locks available
    Function not implemented
    Directory not empty
    Too many levels of symbolic links

  8. #8
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2012
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2012
    Messages : 28
    Points : 9
    Points
    9
    Par défaut
    Enfin ça c'est pas la liste de toutes mes erreurs, mais la liste de toutes les erreurs qu'on peut rencontrer (http://docwiki.embarcadero.com/RADStudio/fr/Sys_errlist), donc je n'ai bien qu'une seule erreur qui est celle du Bad File Descriptor, no ?

  9. #9
    Membre éclairé
    Avatar de Kirilenko
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2011
    Messages
    234
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 27
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 234
    Points : 807
    Points
    807
    Par défaut
    Ton code est si long que ça pour que tu ne puisses pas le poster en entier ?
    En l'occurrence je ne vois pas pourquoi un code comme celui-ci :

    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <unistd.h>
     
    #define FILE_NAME             "essai.txt"
    #define TAILLE_MESSAGE        64
     
    int main(void) {
      char s;
      int i=0, error;
      int fd;
      char message_Lu[TAILLE_MESSAGE];
     
      fd = open(FILE_NAME, O_RDONLY);
     
      if (fd == -1) {
        perror("open");
        return EXIT_FAILURE;
      }
     
      while ((error=read(fd, &s, 1)) > 0)
      {
         message_Lu[i++] = s;
         if(s == '\n')
         {
           message_Lu[i] = '\0';
           break;
         }
      }
     
      printf("%s\n", message_Lu);
     
      if (error<0)
      {
        perror("File descriptor invalide");
        exit(EXIT_FAILURE);
      }
      close(fd);
      return EXIT_SUCCESS;
    }
    ne fonctionnerait pas.
    Récursivité en C : épidémie ou hérésie ?

    "Pour être un saint dans l'Église de l'Emacs, il faut vivre une vie pure. Il faut se passer de tout logiciel propriétaire. Heureusement, être célibataire n'est pas obligé. C'est donc bien mieux que les autres églises" - Richard Stallman

  10. #10
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2012
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2012
    Messages : 28
    Points : 9
    Points
    9
    Par défaut
    Enfaîte je fais communiquer deux programmes indépendants à l'aide d'un tube.

    Donc lorsque je lance le premier programme, celui-ci se dédouble à l'aide d'un fork, le fils se recouvre par le programme que tu vois là (plus ou moins), le père continue sa route.

    Le père écrit dans le tube, le fils lit dans le tube. En paramètres de mon execl j'ai donc transmis mon tube pour qu'ils puissent se connaître.

    Bon donc je vais essayer d'en dire plus pour que vous puissiez m'aider :

    programme1.c

    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
     
     
    int pipe[2];
     
    if(pipe(pipe) != 0)
    {
      fprintf(stderr, "Erreur de création du tube.\n");
      exit(EXIT_FAILURE);
    }
    char pipe_lecture[10];
     
    sprintf(pipe_lecture,"%d", pipe[0]);
     
    p = fork();
     
    if (p==0)
    {
      close(pipe[1]);
      execlp("./programme2", "programme2", pipe_lecture, NULL);
    }
     
    else
    {
      close(pipe[0]);
      sprintf(messageEcrire, "00001111");
      write(pipe[1], messageEcrire, TAILLE_MESSAGE);
    }
    programme2.c
    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
     
    pipe_lecture = atoi(argv[1]);
     
    unsigned char message_Lu[TAILLE_MESSAGE];
     
    //read(pipe_lecture, message_Lu, TAILLE_MESSAGE);
     
    /*Variables temporaires*/
    char s;
    int i=0, error;
     
    while ((error=read(pipe_lecture, &s, 1)) > 0)
    {
       message_Lu[i++] = s;
       if(s == '\n')
       {
         message_Lu[i] = '\0';
         break;
       }
    }
     
    if (error<0)
    {
      perror("File descriptor invalide");
      exit(EXIT_FAILURE);
    }


    Voilà ! Je pense pas que ça puisse vous aider, mais sait-on jamais

  11. #11
    Membre émérite
    Homme Profil pro
    Inscrit en
    Décembre 2011
    Messages
    1 186
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2011
    Messages : 1 186
    Points : 2 502
    Points
    2 502
    Par défaut Msg ci-dessous posté avant d'avoir vu réponse précédente
    Citation Envoyé par Nainpoleon Voir le message
    Enfin ça c'est pas la liste de toutes mes erreurs, mais la liste de toutes les erreurs qu'on peut rencontrer (http://docwiki.embarcadero.com/RADStudio/fr/Sys_errlist), donc je n'ai bien qu'une seule erreur qui est celle du Bad File Descriptor, no ?
    Effectivement. Autant pour moi.

    Erreur n°9 : Bad File Descriptor
    Du coup le problème est dans la récupération du descripteur fd

    fd a le bon type (d'ailleurs il vaut 6 quand je fais un printf dessus)
    Pour moi fd est un pointeur vers une adresse désignant le pipe.
    Normalement l'affichage de l'adresse devrait donner un nombre beaucoup plus grand.

    Je pense donc que le code posté est bon.
    Mais que l'erreur se situe à l'ouverture du pipe / récupération du fd.

  12. #12
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2012
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2012
    Messages : 28
    Points : 9
    Points
    9
    Par défaut
    Ok donc j'ai posté les étapes importantes de la récupération de mon fd aka pipe_lecture aka pipe[0]. Une erreur se serait-elle glissée ?

    Comment le read qui est commentée peut-il marcher... je fais un read sur pipe_lecture dans les deux cas :/.

  13. #13
    Membre éclairé
    Avatar de Kirilenko
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2011
    Messages
    234
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 27
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 234
    Points : 807
    Points
    807
    Par défaut
    Il me semble que read() traite les \0 comme un caractère normal. Il faut donc gérer le cas où read traite ce caractère de fin de chaîne sans s'arrêter. Sinon, le tube continue à être lu.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     while ((ret = read(fd, &c, 1)) > 0) {
        printf("Caractere lu : %c\n", c);
        message_Lu[i++] = c;
        if(c == '\0') {
          break;
        }
      }
    Récursivité en C : épidémie ou hérésie ?

    "Pour être un saint dans l'Église de l'Emacs, il faut vivre une vie pure. Il faut se passer de tout logiciel propriétaire. Heureusement, être célibataire n'est pas obligé. C'est donc bien mieux que les autres églises" - Richard Stallman

  14. #14
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2012
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2012
    Messages : 28
    Points : 9
    Points
    9
    Par défaut
    Eh bien voilà, tu as ma gratitude éternelle, la solution était bien là ! Merci beaucoup Kirilenko

Discussions similaires

  1. Utilisation de read.table
    Par kaleme dans le forum R
    Réponses: 1
    Dernier message: 09/04/2014, 17h14
  2. Réponses: 3
    Dernier message: 23/06/2011, 17h29
  3. Utilisation de read.big.matrix()
    Par aïtaï_tsubasa dans le forum R
    Réponses: 7
    Dernier message: 24/03/2010, 16h42
  4. copie de fichier en utilisant open,read,write
    Par une_tite_question dans le forum POSIX
    Réponses: 3
    Dernier message: 08/09/2008, 14h55
  5. Réponses: 2
    Dernier message: 21/03/2007, 15h13

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