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

Fortran Discussion :

Affecter un Unit à la sortie standard


Sujet :

Fortran

  1. #1
    Membre actif
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2008
    Messages
    464
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Mars 2008
    Messages : 464
    Points : 268
    Points
    268
    Par défaut Affecter un Unit à la sortie standard
    Bonjour,

    J'ai des programmes avec la trame suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
           PROGRAM P1
           
           <Instruction diverse>
           WRITE(13,'(''Message à affecter à la sortie standard'')')
           Instruction diverse
    
           END PROGRAM
    Je souhaite que mon message "Message à affecter à la sortie standard" s'affiche sur mon écran. En d'autre terme, je souhaite que mon unit 13 soit redirigé vers la sortie standard. Je voudrais par exemple faire cette assignation dans un shell de lancement. Est ce que cela se fait?

    Je sais que que je pourrais écrire la ligne suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
          WRITE(6,'(''Message à affecter à la sortie standard'')')
    Mais ce n'est pas ce que je veux.

    Je vous remercie d'avance.

  2. #2
    Modérateur

    Profil pro
    Inscrit en
    Août 2006
    Messages
    974
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Août 2006
    Messages : 974
    Points : 1 346
    Points
    1 346
    Par défaut
    La solution peut varier d'un système à l'autre, mais en gros, tu dois ouvrir le unit 13 sur un fichier correspondant à l'écran. Le résultat n'est pas garantie d'être identique à une sortie stdout, mais c'est assez près.

    Par exemple, il y a quelques années (?), nous avions un programme Fortran roulant sous DOS qui demandait à l'utilisateur le nom du fichier de sortie. En répondant CON (« fichier » console pour DOS), nous obtenions les résultats à l'écran.

  3. #3
    Membre actif
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2008
    Messages
    464
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Mars 2008
    Messages : 464
    Points : 268
    Points
    268
    Par défaut Réponse
    Bonjour, Merci pour la réponse
    En fait mon programme fortran tourne AIX et est lancé par un shell en ksh.
    C'est dans ce shell que je veux affecter mon unit à la sortie standard et je n'ai pas trouvé la commande correspondante

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    488
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 488
    Points : 593
    Points
    593
    Par défaut
    Bonjour,

    Je n'ai pas de réponse directe sur la manière de rediriger l'unit 13 vers la sortie standard comme tu le veux; j'aurai tendance à dire que ce n'est peut-être même pas possible sous Unix & co (quoiqu'il me semble que certains compilateurs proposent des options de compilation de ce genre; penses à regarder la doc du tiens).

    Par contre, puisque tu parles d'un shell de lancement, rien ne t'empêche de régler le problème à ce niveau: On peut par exemple imaginer d'utiliser la commande 'sed' pour automatiquement transformer tous les "write(13," en "write(6," du programme (sans oublier de recompiler celui-ci après).

    Une autre possibilitée (plus propre) est que le numéro d'unité vers lequel se feront les sorties soit demandé à l'utilisateur au niveau du programme:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    program p1
    integer :: outunit
    ! en début de programme, on demande a ce que soit entrée la valeur de l'unité de sortie
    read(5,*) outunit
     
    ! instruction diverses
     
    ! dès qu'il s'agit de faire une sortie, on utilise
    write(outunit,*) "message vers la sortie"
     
    ! instructions diverses
    end program
    Dans ce cas, c'est au niveau du shell que tu fournirai la valeur de 'outunit'; dans le cas ou ce nombre serait 6, les sorties seront à l'écran. Dans le cas ou 'outunit' serait un autre nombre les sortie seront envoyées dans un fichier fort.outunit.
    Mais pour le coup, attention aux cas 'pathologiques' ou 'outunit' correspondrait à 5 (entrée standard) ou 0 (parfois réglé par défaut sur l'erreur standard), ou serait un nombre négatif...; à gérer au niveau du shell ou du programme; si tu veux faire quelque chose de propre.

    Bonne continuation.

    Ehouarn

  5. #5
    Membre actif
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2008
    Messages
    464
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Mars 2008
    Messages : 464
    Points : 268
    Points
    268
    Par défaut
    Je te remerci Ehouarn de ta réponse et l'affectation au unit 6 pour la sortie standard est probablement la modification que j'aurai à faire dans mes sources si je ne trouve pas d'autre solution plus satisfaisante.

    Cependant ce n'est pas si simple !
    En effet, j'explique la situation, j'ai, à ma disposition, 4000 sources fortran tournant sur VAX/VMS que je dois migrer sur UNIX/AIX.

    Les programmes sont lancés par un script DCL (équivalent à un script SHELL sur UNIX). Pour beaucoup d'entre eux on affecte un unit à la sortie standard. (Commant ASSIGN/USER FOR013 SYS$OUTPUT).

    Je pourrais effectivement changer de manière automatique tous les unit affecté à la sortie standard en un unit 6. Mais il se pose deux problèmes:

    - 1) Une routine qui a l'instruction WRITE(13, '(''.... pourrait très bien appartenir à un programme P1 où le unit 13 est affecté à la sortie standard et appartenur à un autre programme P2 où le unit 13 est affecté à un fichier quelconque (instruction DCL : ASSIGN/USER FOR013 FIC.TMP)

    - 2) Pour baucoup de routine, on écrit pas dans un flux directement mais dans une variable contenant le flux (comme tu as écrit précédemment : WRITE(outunit,'(''...) Seulement c'est variable contenant le flux sont passés d'une routine à l'autre par passage de paramètre CALL SubroutineA(outunit,...). Cet échange de paramètres peut remonter sur 3 ou 4 routines. Dès lors il devient très difficile de trouver une logique pour pouvoir changer automatiquement les unit affectés à la sortie standard. D'autant plus que le paramètre peut changer de nom entre la routine appelante et la routine appelée.

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    488
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 488
    Points : 593
    Points
    593
    Par défaut
    Effectivement, tu risques de ne pas pouvoir t'en sortir sans faire un paquet de modifications à la main...
    Sauf si ton compilateur Fortran inclue la possibilité de fixer l'unité à laquelle est rattachée la sortie standard; j'ai le vague souvenir que certains le permettent.

    Bon courage.

  7. #7
    Modérateur

    Profil pro
    Inscrit en
    Août 2006
    Messages
    974
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Août 2006
    Messages : 974
    Points : 1 346
    Points
    1 346
    Par défaut
    La technique utilisée dans tes scripts me rappelle les stratégies utilisées jadis en Fortran 66, avant l'invention des open()...

    Les pistes possibles :
    • Vérifier si ton OS permet de faire des alias de nom de fichier.
    • Switches du compilateur ou de la librairie. Par exemple, le compilateur Intel pour Windows permet de nommer un fichier de sortie à partir d'une variable d'environnement de la forme > SET FORTn=Fichier ou n est le unit.
    • Modifier tous les sources.
    • Renommer les fichiers de sortie (ou les détruire) après le run.
    • Ajouter une procédure générique de open à tes sources (voir ci-après)


    Procédure générique de open :
    • Ton script doit générer un fichier texte contenant les units et les fichiers associés. Disons le fichier DefOpen.txt
    • Tes programmes doivent contenir l'instruction call DefOpen au début.
    • Tu ajoute la routine DefOpen à tous tes programmes. DefOpen.f90 a la forme :

    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
     
    subroutine DefOpen
       implicit none
       character (1024) NomFichier
       integer NumUnit
       integer k
       open(999,file='DefOpen.txt',status='old',ioStat=k)
       if (k /= 0) return
       do
          read(999,*,iostat=k) NumUnit, NomFichier
          if (k /= 0) return
          open(unit=NumUnit, file=NomFichier, ...,iostat=k)
          if (k /= 0) return
       enddo
       ...
    Il est évidemment possible d'ajuster la procédure afin de traiter des informations plus spécifiques...

  8. #8
    Membre actif
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2008
    Messages
    464
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Mars 2008
    Messages : 464
    Points : 268
    Points
    268
    Par défaut pas besoin du fichier DefOpen.txt
    Bonjour Sylvain et merci pour ta réponse.

    Ce que je crois que ce que tu me proposes est faisable en FORTRAN/IBM/AIX sans utilisation du fichiers de gestion d'ouverture de fichiers et d'assignation à un flux (DefOpen.txt dans ton exemple).

    En effet, j'ai regardé dans la doc FORTRAN XLF (le FORTRAN que j'utilise) et l'ai testé derrière : il me suffit de créer un script shell de lancement de fichier dans lequel j'ai les instruction suivantes:
    début du shell :
    XLFRTEOPTS "unit_vars=yes"
    XLFUNIT_unit1 = fic1
    XLFUNIT_unit2 = fic2
    ...
    export XLFRTEOPTS XLFUNIT_unit1 XLFUNIT_unit2
    programme

    fin du shell :
    (Cette technique ne nécessite pas d'option de compilation spécifique)

    Ainsi je n'ai pas à modifier les instructions du type :
    OPEN(unit, iostat=...)
    en instruction du type :
    OPEN(unit, NomFichier, iostat=...).

    Cela fonctionne bien!

    Cependant dans mon shell, je n'arrive pas à affecter un unit (différent de 6) à la sortie standard et je ne l'ai pas trouvé dans la doc XLF
    En fait ce, qu'il me faudrait c'est une instruction du type :
    XLFUNIT_unit=stdout (j'ai déjà essayé ça, ça ne fonctionne pas)

  9. #9
    Modérateur

    Profil pro
    Inscrit en
    Août 2006
    Messages
    974
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Août 2006
    Messages : 974
    Points : 1 346
    Points
    1 346
    Par défaut
    Citation Envoyé par VITALTH Voir le message
    ...j'ai regardé dans la doc FORTRAN XLF (le FORTRAN que j'utilise) et l'ai testé derrière : il me suffit de créer un script shell de lancement de fichier dans lequel j'ai les instruction suivantes:
    début du shell :
    XLFRTEOPTS "unit_vars=yes"
    XLFUNIT_unit1 = fic1
    XLFUNIT_unit2 = fic2
    ...
    export XLFRTEOPTS XLFUNIT_unit1 XLFUNIT_unit2
    programme

    fin du shell :
    ...
    Cela fonctionne bien!

    Cependant dans mon shell, je n'arrive pas à affecter un unit (différent de 6) à la sortie standard et je ne l'ai pas trouvé dans la doc XLF
    En fait ce, qu'il me faudrait c'est une instruction du type :
    XLFUNIT_unit=stdout (j'ai déjà essayé ça, ça ne fonctionne pas)
    Je ne peux pas continuer à t'aider. Je connais très peu Unix. Il y a certainement un nom de fichier symbolique correspondant à la console ou à stdout. Essaye du côté du forum Unix

  10. #10
    Membre actif
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2008
    Messages
    464
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Mars 2008
    Messages : 464
    Points : 268
    Points
    268
    Par défaut
    Merci Sylvain
    J'avais effectivement posté une discussion du même genre sur le forum unix partie AIX. Je n'ai pas eu de réponse.

    Comme j'avais découvert l'instruction :
    XLFRTEOPTS "unit_vars=yes"
    ...
    export XLFRTEOPTS XLFUNIT_...

    dans la doc FORTRAN XLF, je supposais que ce sujet était plus adapté ici

  11. #11
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    488
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 488
    Points : 593
    Points
    593
    Par défaut
    C'est bien dommage si xlf ne permet pas d'imposer le numéro logique associée à la sortie standard.
    Je viens de regarder vite fait, et g95 permet par contre exactement ce genre de manipulation (via la variable d'environnement G95_STDOUT_UNIT si on en croit la doc http://ftp.g95.org/G95Manual.fr.pdf ).
    Mais bon, j'imagine bien que changer de compilateur n'est pas forcément une solution des plus acceptables.

  12. #12
    Membre actif
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2008
    Messages
    464
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Mars 2008
    Messages : 464
    Points : 268
    Points
    268
    Par défaut
    C'est à vérifier, il y a juste que les options de compilation prise dans le xlf fonctionne ont leur équivalent sur g95.

    Exemple : pour compiler un source voici toutes les option de compilation prises:

    COMP=xlf
    OPTS= -c -g -qsource -qfixed=132 -qintlog -qport=nullarg -qnullterm -qalign=struct=packed -qctyplss -qsave=defaultinit -qinitauto -qescape

    Et ceci sans compter les options de précompilation

  13. #13
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    488
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 488
    Points : 593
    Points
    593
    Par défaut
    Il te faudrait effectivement bien vérifier que/si il y a tous les options de compilations équivalentes avec g95.
    Mais là je ne peux pas grand chose pour toi (à part te souhaiter bon courage) vu que je n'utilise pas xlf...

    Bon courage.

  14. #14
    Modérateur

    Profil pro
    Inscrit en
    Août 2006
    Messages
    974
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Août 2006
    Messages : 974
    Points : 1 346
    Points
    1 346
    Par défaut
    Un peu tard, mais...

    Le « fichier » correspondant au stdin semble être « /dev/tty ». Voir http://groups.google.com/group/comp....a2ee5b9d77453#

    Peut-être « /dev/tty » pourrait-il aussi fonctionner pour stdout ?

  15. #15
    Membre actif
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2008
    Messages
    464
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Mars 2008
    Messages : 464
    Points : 268
    Points
    268
    Par défaut
    Oui je pense que c'est une bonne idée, en effet /dev/tty traite de tous les entrée sortie avec le terminal. Je vais tester si tot que je serais sur ma machine de test.

    Cependant dans mon korn shell d'appel je ne sais pas trop comment je peux déclarer les choses peut être un truc du genre

    XLFUNIT_13=/dev/tty

    Bref je vais essayer et je vous tiens au courant du test

  16. #16
    Membre actif
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2008
    Messages
    464
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Mars 2008
    Messages : 464
    Points : 268
    Points
    268
    Par défaut Ca marche
    Merci Sylvain
    Cela fonctionne enfin :

    la méthode utilisée est :
    crée un script shell p1.ksh
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    #! /usr/bin/ksh
    XLFRTEOPTS=unit_vars=yes
    XLFUNIT_13=/dev/tty
    export XLFRTEOPTS XLFUNIT_13
    p1
    et d'avoir mon programme p1.f
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
          PROGRAM P1
          WRITE(13,'(''MON MESSAGE SUR LA SORTIE STANDARD'')')
          STOP
          END
    En compilant et en linkanbt avec XLF :
    xlf p1.f -o p1

    on obtient :
    $ ./p1.ksh
    MON MESSAGE SUR LA SORTIE STANDARD

    Merci pour ton aider cela me sort une grosse épine du pied

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

Discussions similaires

  1. PB sortie standard avec les PTHREAD !!!
    Par djspit dans le forum C++
    Réponses: 15
    Dernier message: 19/11/2004, 01h17
  2. [langage] sortie standard linux
    Par ebaynaud dans le forum Langage
    Réponses: 8
    Dernier message: 14/10/2004, 08h05
  3. rediriger la sortie standard vers un textarea
    Par gromite dans le forum Composants
    Réponses: 9
    Dernier message: 10/05/2004, 11h07
  4. Réponses: 5
    Dernier message: 24/12/2003, 09h49
  5. Réponses: 16
    Dernier message: 18/07/2003, 17h16

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