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 :

Peut-on modifier la sortie standard (stdout) ?


Sujet :

C

  1. #1
    Membre éprouvé
    Profil pro
    Eleveur de cornichons
    Inscrit en
    Juin 2002
    Messages
    1 074
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Eleveur de cornichons
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 074
    Points : 1 166
    Points
    1 166
    Par défaut [Resolu]Peut-on modifier la sortie standard (stdout) ?
    Bonjour

    J'ai lu dans un cours de IUT informatique :
    Conseil : Ne transformer et ne renommer pas les flots standards si ce n'est pas nécessaire
    J'en déduis que c'est quand meme possible ?!
    Alors je voudrais savoir si je peux modifier stdout.
    Ma question est purement théorique et j'en n'ai pas besoin dans une application !
    Par exemple, la fonction getch() n'utilise pas de mémoire tampon et l'information est directement envoyée à stdin.
    Par contre, getchar() utilise la mémoire tampon et l'information n'est envoyée qu'après avoir validé ! Et on voit ce que l'on tape !

    Donc , comment la fonction getchar() peut-elle envoyer les informations à stdout après validation ? C'est surement un simple "putchar" par exemple qui est utilisé ... mais je me demande si on peut modifier le flux stdout pour que les caractères renvoyé soit que des étoiles (*).
    Ce sujet a deja été traité a propos des mots de passes, mais ma question porte sur le flux lui meme et non une fonction qui remplace les char rentré par des étoiles.
    Merci d'avance en espérant avoir été clair

    Nas'

  2. #2
    Candidat au Club
    Profil pro
    Inscrit en
    Septembre 2002
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2002
    Messages : 2
    Points : 2
    Points
    2
    Par défaut
    bas stdout c'est ce qui s'affiche sur l'écran je crois.
    Donc même avec getchar, l'info est envoyer avant de valider, ce que tu valide c'est si ce que tu tape ce transforme en donné ou pas.
    Enfin je crois.
    Signature:
    Ceci est un bloc de texte qui peut être ajouté aux messages que vous postez. Il y a une limite de 255 caractères

  3. #3
    Membre éprouvé
    Profil pro
    Eleveur de cornichons
    Inscrit en
    Juin 2002
    Messages
    1 074
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Eleveur de cornichons
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 074
    Points : 1 166
    Points
    1 166
    Par défaut
    lut

    Je viens de rentrer chez moi et tu viens de repondre, qq hasard
    Bref, je crois que, comme je l'ai dit, getchar() utilise la mémoire tampon, donc les infos tapée ne sont pas envoyée à stdin mais mis dans un emplacement en mémoire (buffer) et une fois entrée pressée, les infos sont envoyées à stdin...
    Bref, stdout n'est pas forcément que l'écran. A la base c'est ca pour tout programme C, mais on peur rediriger les infos de stdout vers un fichier par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    C:/> NomExectuable >> fichier.txt
    Tout ce qui est sensé être envoyé à l'écran (donc stdout) se verra envoyé au fichier... donc c'est ce genre de truc qui me trouble... il y a bien un moyen de modifier stdout... et non pas que la redirection mais également les données transmises.
    Par exemple que tout appel de printf, putchar, puts, fprintf(stdout,"texte") , ...envoie à stdout non pas les infos transmises en argument, mais que des étoiles ... possible ?!
    Merci d'avoir repondu deja

    Nas'

  4. #4
    Membre expérimenté
    Avatar de nyal
    Profil pro
    Inscrit en
    Septembre 2002
    Messages
    622
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2002
    Messages : 622
    Points : 1 428
    Points
    1 428
    Par défaut
    Bonjour,

    Je ne te suis pas Nasky. Ce n'est pas clair.
    Tu peux rediriger stdout vers un fichier via des fonctions systemes comme dup et dup2. Mais ce n'est surement pas ce que tu veux.
    Tu peux jouer avec stdout en le redirigeant puis restaurant.
    Il faudrait etre plus precis sur l'exemple.

  5. #5
    Membre éprouvé
    Profil pro
    Eleveur de cornichons
    Inscrit en
    Juin 2002
    Messages
    1 074
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Eleveur de cornichons
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 074
    Points : 1 166
    Points
    1 166
    Par défaut
    Citation Envoyé par nyal
    Je ne te suis pas Nasky. Ce n'est pas clair.
    Je sais , moi-meme j'arrive pas très bien à me comprendre .
    Ce que je m'imagine c'est ca :
    on envoie l'information à la fonction getche() par exemple ! Cette fonction n'utilise pas la mémoire tampon mais envoie l'information tapée à stdin "en live" , donc directement après avoir tapé une lettre. Puis on voit s'afficher les lettres que l'on tape , à l'écran...
    Le truc que je me demande c'est ici qu'il se passe. Ce que je tape, supposons bonjour, je tape tout d'abord b et le code ascii est envoyé à stdin, qui emet un echo donc qui envoie ce code ascii à stdout. A ce moment la, il y a surement un "truc" qui se passe, qch qui permet en qq sorte l'échange d'information entre stdin et stdout...
    Peut-on intervenir dans cet "échange" pour que tous les caractères soit remplacé par une étoile (*) donc en fait, modifier le code ascii de tous les char en le remplacement par celui de l'étoile mais juste lorsque l'information est envoyée à stdout et pas ailleurs. Donc dans stdin, on a tjs le code ascii de chaque char normalement, mais l'information envoyée à stdout contient que celui de l'étoile et donc l'information affichée sera de la meme longueur que mon mot (bonjour) mais avec des étoiles ******* .
    (je ne parle pas d'une fonction qui le fait après l'envoie d'information, mais lors de l'envoie d'information lui meme !)
    J'espère que c'est clair

    Nas'

    Edit : le truc en plus, c'est que le mot tapé est remplacé par des étoiles mais si je selectionne le 2eme char du mot (bonjour), et que j'affiche son code ascii, il m'affiche bien le code ascii de "o" et non de "*" , mais l'affichage lui est qd mm avec des étoiles.

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    71
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 71
    Points : 78
    Points
    78
    Par défaut
    Je ne pense pas qu'il y ait un 'écho' automatique de stdin vers stdout, mais je pense que c'est la fonction utilisée (ici getche) qui le fasse. Tu connais getch et getche ? getch() n'affiche pas le caractère tapé, et dans ton concept, cela voudrait dire que getch enlève explicitement le caractère pour qu'il n'apparraisse pas. Je pense que getche ENVOIE explicitement le caractère vers stdout (d'ailleurs le 'e' de getche veut dire 'écho'), donc l'échange stdin <-> stdout est fait par la fonction getche (facile à réécrire en réutilisant getch) et non implicitement (oui, j'ai cherché).
    Encore un truc : tu as dit que getche ENVOIE l'information à stdin mais je pense que c'est dans ce sens que ça se fait : les informations (caractères tapés) sont présentes dans stdin (dans une sorte de queue, un buffer ?). Getch / scanf / ... prend ces informations, les traite, puis les affiche (envoi vers stdout) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    stdin -> (code de caractère) -> getche -> stdout 
                                           -> valeur de retour
    contrairement à getch :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    stdin -> (code de caractère) -> getche -> valeur de retour

  7. #7
    Membre éprouvé
    Profil pro
    Eleveur de cornichons
    Inscrit en
    Juin 2002
    Messages
    1 074
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Eleveur de cornichons
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 074
    Points : 1 166
    Points
    1 166
    Par défaut
    Oui je savais cela, c'est ce que j'ai dit plus haut, non ?
    Enfin de toute facon, Nyal m'a donné une réponse en privé, je vais la tester et si elle marche, je vais la poster ici si ca interesse qqn.
    Je pensais modifier les infos envoyées par stdout mais ca ne semble pas etre possible comme je le pensais.
    Meme des personnes de niveaux avancés en C (sur IRC) ne savent pas comment faire
    Enfin je reviendrais

    Nas'

  8. #8
    Responsable technique

    Avatar de Anomaly
    Homme Profil pro
    Directeur
    Inscrit en
    Juin 2003
    Messages
    10 335
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Directeur
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2003
    Messages : 10 335
    Points : 130 269
    Points
    130 269
    Billets dans le blog
    1
    Par défaut
    Si tu utilises les fonctions getch() ou getche(), sous DOS ou Windows, j'ai le regret de t'informer qu'elles ne passent pas par le flux d'entrée/sortie standard. Donc même si tu rediriges, tu en seras pour tes frais
    Responsable technique forum & site

    Si ce message (ou un autre) vous a aidé et/ou vous semble pertinent, votez pour lui avec

  9. #9
    Membre éprouvé
    Profil pro
    Eleveur de cornichons
    Inscrit en
    Juin 2002
    Messages
    1 074
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Eleveur de cornichons
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 074
    Points : 1 166
    Points
    1 166
    Par défaut
    Citation Envoyé par Anomaly
    Si tu utilises les fonctions getch() ou getche(), sous DOS ou Windows, j'ai le regret de t'informer qu'elles ne passent pas par le flux d'entrée/sortie standard.
    Bas si ! getch() et getche() ne sont pas normalisées certes, mais elles envoyent bien les données à stdin, et getche() fait bien un echo vers stdout !
    De tt facon, ce que je veux est impossible, j'ai testé le code de Nyal mais il permet juste d'afficher des étoiles après avoir validés, pas en temps réel à la place des blancs de getch().
    Je laisse tomber . Merci pour votre aide

    Nas'

  10. #10
    fd
    fd est déconnecté
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    131
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 131
    Points : 162
    Points
    162
    Par défaut
    He non !
    Anomaly à parfaitement raison ces fonctions ne passent pas par stdin/stdout, elles passent "dessous" (par un appel bios si je me souviens bien)

  11. #11
    Membre éprouvé
    Profil pro
    Eleveur de cornichons
    Inscrit en
    Juin 2002
    Messages
    1 074
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Eleveur de cornichons
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 074
    Points : 1 166
    Points
    1 166
    Par défaut
    Je conteste pas alors si tous les deux ditent ca.
    Mais ou avez vous lu cela ?? Car dans tous les cours/tutos/livres , on lit "stdin" pour getch, getche() ... Je comprend pas !
    Est-ce getchar aussi est dans le meme cas ?

    Nas'

  12. #12
    Responsable technique

    Avatar de Anomaly
    Homme Profil pro
    Directeur
    Inscrit en
    Juin 2003
    Messages
    10 335
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Directeur
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2003
    Messages : 10 335
    Points : 130 269
    Points
    130 269
    Billets dans le blog
    1
    Par défaut
    Standard ANSI :
    getchar() est équivalent à getc(stdin), qui est lui-même équivalent à fgetc(stdin) qui est équivalent à lire 1 octet sur stdin, donc à faire un fread(&octet, 1, 1, stdin); mais fgetc est plus rapide, et getc susceptible de l'être davantage parce que c'est une macro-commande.

    Les flux ANSI sont prévus d'être redirigés. Le DOS offre cette capacité. Mais le problème c'est que le DOS, hormis la redirection, ne t'offre aucune autre fonction, genre lecture en mode brut (lecture d'un caractère pur), affichage des couleurs, et de plus elles sont lentes.

    Borland a donc inventé la fonction getch() qui est équivalent à bioskey(0), getche() qui fé la même chose mais qui affiche du texte. Dans tous les cas, ces fonctions n'utilisent pas le DOS, mais le BIOS. Plus de contrôle, mais ça ignore totalement les redirections qui n'existent qu'en DOS. Idem pour l'affichage ; c'est pas pour rien qu'on appelle cprintf qui passent par le BIOS ou directement en écrivant dans la mémoire vidéo, contrairement à printf qui passe par le DOS, sans couleur ni rien, mais qui est susceptible d'être redirigé.

    Pour info sous Unix, on passe toujours par les flux, car pour afficher des couleurs les séquences spéciales existent (ANSI), et il est possible de configurer le flux pour lire les caractères en mode brut. Donc on utilise bien getchar() et printf() pour ce même usage.
    Responsable technique forum & site

    Si ce message (ou un autre) vous a aidé et/ou vous semble pertinent, votez pour lui avec

  13. #13
    Futur Membre du Club
    Inscrit en
    Mars 2003
    Messages
    4
    Détails du profil
    Informations forums :
    Inscription : Mars 2003
    Messages : 4
    Points : 5
    Points
    5
    Par défaut ok
    si tu travaille sous linux le seul intermlediaire qui agit lors de l'utilisation des foncions standard comme printf ou getchar c'est le fihier stty
    donc sous linux t'as po les fonctions du dos comme getch ou getche
    mais tu peux les construiregrace a termio.h ou faire une methode si simple quelle sagit d'utiliser une simple routine pour lire le fichier stty et en afiicher le dernier caractere saisie
    Le sage ne dit pas ce qu'il sait, le sot ne sait pas ce qu'il dit et le vrai programmeur sait ce qu'il fait

  14. #14
    fd
    fd est déconnecté
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    131
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 131
    Points : 162
    Points
    162
    Par défaut
    d'ailleur c'est trés simple de t'en appercevoir.
    fais un petit programme (coucou.exe) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    void main()
    {
      int vc;
      for(vc = 0;vc < 50;vc++)
       cprintf("Coucou\n");
    }
    et fait
    coucou | more
    et tu verra qu'il ignore superbement le more

    remplace cprintf() par printf() et le more marchera

  15. #15
    Membre à l'essai
    Inscrit en
    Février 2003
    Messages
    47
    Détails du profil
    Informations forums :
    Inscription : Février 2003
    Messages : 47
    Points : 24
    Points
    24
    Par défaut
    Anomaly :
    c'est pas pour rien qu'on appelle cprintf qui passent par le BIOS ou directement en écrivant dans la mémoire vidéo, contrairement à printf qui passe par le DOS, sans couleur ni rien, mais qui est susceptible d'être redirigé.
    J'ai vu en effet dans des cours des exemples ou l'on affiche une phrase en couleur a l'aide de cprintf(). Mais j'ai essayé avec printf() tout simplement et ça a marché. ex :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    #include <conio.h>
    #include <stdio.h>
     
    int main()
    {
      textcolor(YELLOW) ;
      printf("coucou") ;        // meme effet que cprintf("coucou") a priori
     
      return 0 ;
    }
    Ma question est : pourquoi ici printf() a le meme effet que cprintf() ?

  16. #16
    fd
    fd est déconnecté
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    131
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 131
    Points : 162
    Points
    162
    Par défaut
    parceque le dos (stdout via printf) appelle en définitive le bios (comme cprintf) pour faire effectivement l'affichage

  17. #17
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 750
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 750
    Points : 10 670
    Points
    10 670
    Billets dans le blog
    3
    Par défaut
    J'apporte mon grain de sel en disant que le BIOS sous Windows c'est fini.
    Ca travaille directement avec la console, même si l'entrée standard est redirigée. Du moins, sous Windows avec VC++.
    Tu peux réouvrir stdin / stdout / stderr avec freopen sinon.
    Si tu veux des infos sur la lib standard, le mieux c'est de consulter ses sources, dans le répertoire crt de VC++ ou du SDK.

    (...)\SDK\src\crt\getch.c
    /***
    *getch.c - contains _getch(), _getche(), _ungetch() and kbhit for Win32
    *
    * Copyright (c) 1989-2001, Microsoft Corporation. All rights reserved.
    *
    *Purpose:
    * Defines the "direct console" functions listed above.
    *
    * NOTE: The real-mode DOS versions of these functions read from
    * standard input and are therefore redirected when standard input
    * is redirected. However, these versions ALWAYS read from the console,
    * even when standard input is redirected.
    *
    *******************************************************************************/

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 5
    Dernier message: 05/01/2013, 16h26
  2. Lire la sortie standard (stdout) avec Qt
    Par LittleWhite dans le forum Qt
    Réponses: 8
    Dernier message: 15/01/2010, 22h22
  3. [Lazarus] Ecrire sur la sortie standard stdout
    Par SergioMaster dans le forum Lazarus
    Réponses: 4
    Dernier message: 27/09/2009, 14h00
  4. rediriger la sortie standard vers un textarea
    Par gromite dans le forum Composants
    Réponses: 9
    Dernier message: 10/05/2004, 11h07
  5. Réponses: 5
    Dernier message: 24/12/2003, 09h49

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