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 :

Récupérer contenu d'un flux sans retour à la ligne


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France, Indre et Loire (Centre)

    Informations forums :
    Inscription : Avril 2003
    Messages : 7
    Par défaut Récupérer contenu d'un flux sans retour à la ligne
    bonjour,

    je cherche à lancer un exécutable et à lui envoyer un flux et recevoir sa sortie
    j'ai trouvé un code permettant de rediriger les flux.. tout marche bien sauf dans certains cas où l'utilisateur est solicité pour répondre à une question cependant celle-ci ne semble pas être suivi d'un retour à la ligne.. et donc read ne la détecte jamais (ou après la réponse de l'utilisateur ce qui est embetant)

    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
    int main(int argc, char **argv)
    {
        int tube_1[2];
        int tube_2[2];
        if ((pipe(tube_1) != 0) || (pipe(tube_2) != 0))
          return 0;
        switch (fork()) {
          case -1 :
           close(tube_1[0]); close(tube_1[1]);
            close(tube_2[0]); close(tube_2[1]);
          return 0;
          case 0 :
            close(tube_1[1]);
            close(tube_2[0]);
            dup2(tube_1[0], STDIN_FILENO);
            close(tube_1[0]);
            dup2(tube_2[1], STDOUT_FILENO);
            close(tube_2[1]);
         execv ("echo2.sh", NULL);   
            exit(EXIT_SUCCESS);
          default :
            close(tube_1[0]);
            close(tube_2[1]);
        }
    //lecture du flux provenant de l'éxecutable
    char nom[256]="";
         while( read(tube_2[0],nom,1)==1){
        	cout << nom ;
         }
    }
    le code est simplifié pour ne montrer que la redirection de flux et la partie lecture.

    par exemple si l'exécutable effecture la commande suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sudo apt-get remove filezilla
    et bien
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Souhaitez-vous continuer [O/n]?
    n'apparait qu'après la réponse de l'utilisateur....

    Donc je cherche le moyen de récupérer le contenu du flux avant le retour à la ligne...

    je précise que je n'ai jamais touché ni au C ni au C++ mais j'ai juste besoin de cette fonction.. alors je suppose que le code est loin d'être parfait

    merci d'avance pour vos réponses

  2. #2
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    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 835
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par une maison en bois Voir le message
    bonjour,

    je cherche à lancer un exécutable et à lui envoyer un flux et recevoir sa sortie
    j'ai trouvé un code permettant de rediriger les flux.. tout marche bien sauf dans certains cas où l'utilisateur est solicité pour répondre à une question cependant celle-ci ne semble pas être suivi d'un retour à la ligne.. et donc read ne la détecte jamais (ou après la réponse de l'utilisateur ce qui est embetant)

    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
    int main(int argc, char **argv)
    {
        int tube_1[2];
        int tube_2[2];
        if ((pipe(tube_1) != 0) || (pipe(tube_2) != 0))
          return 0;
        switch (fork()) {
          case -1 :
           close(tube_1[0]); close(tube_1[1]);
            close(tube_2[0]); close(tube_2[1]);
          return 0;
          case 0 :
            close(tube_1[1]);
            close(tube_2[0]);
            dup2(tube_1[0], STDIN_FILENO);
            close(tube_1[0]);
            dup2(tube_2[1], STDOUT_FILENO);
            close(tube_2[1]);
         execv ("echo2.sh", NULL);   
            exit(EXIT_SUCCESS);
          default :
            close(tube_1[0]);
            close(tube_2[1]);
        }
    //lecture du flux provenant de l'éxecutable
    char nom[256]="";
         while( read(tube_2[0],nom,1)==1){
        	cout << nom ;
         }
    }
    le code est simplifié pour ne montrer que la redirection de flux et la partie lecture.

    par exemple si l'exécutable effecture la commande suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sudo apt-get remove filezilla
    et bien
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Souhaitez-vous continuer [O/n]?
    n'apparait qu'après la réponse de l'utilisateur....

    Donc je cherche le moyen de récupérer le contenu du flux avant le retour à la ligne...

    je précise que je n'ai jamais touché ni au C ni au C++ mais j'ai juste besoin de cette fonction.. alors je suppose que le code est loin d'être parfait

    merci d'avance pour vos réponses
    Mon expérience en matière de programmation à base de dup2() est quasi nulle. Je me suis juste amusé une fois à recréer un pipe entre "x" commandes un peu comme tu le fais mais ça date de 3 ans. Juste pour dire que je vois pas (plus) pourquoi tu fermes les cotés du tube que t'as dupliqué dans stdin et stdout.
    Sinon ton appel execv() est mauvais. Tu dois lui passer en argument
    n° 2 la liste des arguments que ton programme recevra. Or, un programme reçoit toujours son nom en argument [0] donc la liste des arguments n'est jamais nulle.
    Je te conseillerais de passer plutôt par execl() si t'as pas envie de te fatiguer à recréer un char *[]
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    execl("echo2.sh", "echo2.sh", NULL)
    Sinon pour répondre à ta question, la fonction "read()" n'attend pas spécialement de '\n' donc ça vient pas de là.
    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
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France, Indre et Loire (Centre)

    Informations forums :
    Inscription : Avril 2003
    Messages : 7
    Par défaut
    Bon j'ai un problème un peu étrange.
    J'ai parcouru tes cours (très bien fait dailleurs)
    et j'ai créé flux entre 2 processus avec mkfifo

    je redirige ensuite la sortie (stdout) du premier processus vers le flux
    et je le lis avec l'autre processus (j'ai essayé fgets.. fgetc.. read etc..)

    et bien lors du
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sudo apt-get remove filezilla
    (exécuter par le premier processus)
    la dernière ligne n'apparait toujours pas...


    Alors que si je redirige le flux vers le Stdin tu 2e processus.. et que je fais :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    while(true){
     cin >> donnee;
    cout << donnee;
    }
    la dernière ligne s'affiche...

    je ne comprends pas....

    Sinon pour répondre à ta question, la fonction "read()" n'attend pas spécialement de '\n' donc ça vient pas de là.
    Tu as raison j'ai simulé une chaine sans "\n" et il l'affiche sans problème.. je sais pas mais il y'a quelque chose qui bloque
    que ça soit en utilisant fgetc, fgets ou read ça reste bloqué arrivé à cette fameuse ligne...

    et la solution de me contenter du stdin ne me plait pas parce que je dois aussi récupérer le stderr séparément.. donc je ne pourrais pas ainsi :/
    ou alors lancé un 3e processus qui récupère le stderr sur son stdin mais ça me semble bancale nan ?

  4. #4
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France, Indre et Loire (Centre)

    Informations forums :
    Inscription : Avril 2003
    Messages : 7
    Par défaut
    J'ai toujours pas trouvé la solution à mon problème mais j'ai trouvé ça :

    Alors que si je redirige le flux vers le Stdin tu 2e processus.. et que je fais :

    Code :

    while(true){
    cin >> donnee;
    cout << donnee;
    }

    la dernière ligne s'affiche...
    Parcontre avec cin.getline je retrouve le même problème qu'avec les autres méthodes... Il y'a donc bien quelque chose qui empêche la lecture complète de cette dernière ligne !!

    si ça peut aider quelqu'un à trouver....

Discussions similaires

  1. Réponses: 2
    Dernier message: 05/12/2013, 15h55
  2. Récupérer contenu d'un Span sans id
    Par oni13 dans le forum Général JavaScript
    Réponses: 5
    Dernier message: 05/06/2012, 10h31
  3. Ma liste à puce sans retour à la ligne ?
    Par ChrissBob dans le forum Balisage (X)HTML et validation W3C
    Réponses: 6
    Dernier message: 23/08/2011, 13h05
  4. Scanf sans retour à la ligne
    Par mello dans le forum C
    Réponses: 10
    Dernier message: 11/11/2005, 17h22
  5. TMemo sans retour à la ligne
    Par da_latifa dans le forum Composants VCL
    Réponses: 6
    Dernier message: 22/08/2005, 08h23

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