writing output listing onto screen (or not) and onto file 
Author Message
 writing output listing onto screen (or not) and onto file

           Is it possible to simplify my code by putting only one
WRITE statement when I want to write output results onto screen
(or not) and onto a file :

I put :

       CHARACTER*1 SEL

       OPEN( 8,FILE='sosout')

       WRITE(6,*) '     Sorties en ligne (o | n ou >)?'
       READ (5,'(A)') SEL
       IF(SEL.NE.'o') OPEN(6,FILE='NO')

       WRITE(6,200) A, B, C
       WRITE(8,200) A, B, C
  200  FORMAT('  A B C=', 3F12.4)
       ............;

      Thanks for your help!

Bernard Bru



Fri, 02 Jan 2009 15:59:28 GMT  
 writing output listing onto screen (or not) and onto file
Quote:

>           Is it possible to simplify my code by putting only one
> WRITE statement when I want to write output results onto screen
> (or not) and onto a file :

Are you asking about facilities provided by most systems for redirecting
output sent to '*' (or, on many systems, unit 6 without an OPEN)?
For example, the tee program, or redirection using '>' on the command line?


Fri, 02 Jan 2009 20:37:13 GMT  
 writing output listing onto screen (or not) and onto file

Quote:


>>           Is it possible to simplify my code by putting only one
>> WRITE statement when I want to write output results onto screen
>> (or not) and onto a file :

> Are you asking about facilities provided by most systems for redirecting
> output sent to '*' (or, on many systems, unit 6 without an OPEN)?
> For example, the tee program, or redirection using '>' on the command line?

Sorry, perhaps I'm not so clear:

Some time I want to have at the same time output on screen (Unit 6 or *)
and onto a file (OPEN(8,FILE= 'sosout')
An an other time I want only output on file (here unit 8) (for me it is
easier to visualize the output using vim editor) So I put in this case
OPEN(6,FILE= 'NO') because I dont need it

It seems to me heavy to put in the code 2 WRITE's for each output!!!

WRITE(6,....................
WRITE(8, the same as above

Bernard Bru



Fri, 02 Jan 2009 20:57:06 GMT  
 writing output listing onto screen (or not) and onto file

Quote:

> Some time I want to have at the same time output on screen (Unit 6 or *)
> and onto a file (OPEN(8,FILE= 'sosout')
> An an other time I want only output on file (here unit 8) (for me it is
> easier to visualize the output using vim editor) So I put in this case
> OPEN(6,FILE= 'NO') because I dont need it

What about this:

   integer, parameter :: USR_UNIT(2) = [6, 8]
   integer i
   logical StdOutput, FileOutput
   real a, b, c

   a = 1.; b = 2.; c = 3.

   write(*, '("Std output? [T/F]: ")', ADVANCE = 'NO')
   read(*, *) StdOutput

   write(*, '("File? [T/F]: ")', ADVANCE = 'NO')
   read(*, *) FileOutput

   if (FileOutput) Open(unit = USR_UNIT(2), file = 'userfile.txt')

   do i = 1, 2
      if (i == 1 .AND. (.NOT.StdOutput)) cycle
      if (i == 2 .AND. (.NOT.FileOutput)) cycle
      write(USR_UNIT(i), "('  A B C=', 3F12.4)")  a, b, c
   enddo



Fri, 02 Jan 2009 22:09:25 GMT  
 writing output listing onto screen (or not) and onto file

Quote:


>>Some time I want to have at the same time output on screen (Unit 6 or *)
>>and onto a file (OPEN(8,FILE= 'sosout')

>>An an other time I want only output on file (here unit 8) (for me it is
>>easier to visualize the output using vim editor) So I put in this case
>>OPEN(6,FILE= 'NO') because I dont need it

> What about this:

>    integer, parameter :: USR_UNIT(2) = [6, 8]
>    integer i
>    logical StdOutput, FileOutput
>    real a, b, c

>    a = 1.; b = 2.; c = 3.

>    write(*, '("Std output? [T/F]: ")', ADVANCE = 'NO')
>    read(*, *) StdOutput

>    write(*, '("File? [T/F]: ")', ADVANCE = 'NO')
>    read(*, *) FileOutput

>    if (FileOutput) Open(unit = USR_UNIT(2), file = 'userfile.txt')

>    do i = 1, 2
>       if (i == 1 .AND. (.NOT.StdOutput)) cycle
>       if (i == 2 .AND. (.NOT.FileOutput)) cycle
>       write(USR_UNIT(i), "('  A B C=', 3F12.4)")  a, b, c
>    enddo

I tried to compile your code: it works with g95, ifort and pgf90 but not
with f90 of Sun; error messages are:

    integer, parameter :: USR_UNIT(2) = [6, 8]
                                        ^
"io.f90", Line = 2, Column = 40: ERROR: Unexpected syntax: "operand" was
expected but found "[".
                                            ^
"io.f90", Line = 2, Column = 44: ERROR: Unexpected syntax: "object-name"
was expected but found "8".

f90: COMPILE TIME 0.090000 SECONDS
f90: MAXIMUM FIELD LENGTH 4282502 DECIMAL WORDS
f90: 22 SOURCE LINES
f90: 2 ERRORS, 0 WARNINGS, 0 OTHER MESSAGES, 0 ANSI

nor with f95 of NAG :

Error: io.f90, line 2: Illegal character '['
Error: io.f90, line 2: syntax error
***Invalid item in type declaration
Error: io.f90, line 2: Illegal character ']'
[f95 terminated - errors found by pass 1]

I'm not a specialist of fortran 90!!

Your solution seems to me to heavy because I have hundred of writes in
my code!!

Thanks a lot for your ansver

Bernard Bru



Fri, 02 Jan 2009 23:15:09 GMT  
 writing output listing onto screen (or not) and onto file

Quote:

> I tried to compile your code: it works with g95, ifort and pgf90 but not
> with f90 of Sun; error messages are:

>     integer, parameter :: USR_UNIT(2) = [6, 8]
>                                         ^
> "io.f90", Line = 2, Column = 40: ERROR: Unexpected syntax: "operand" was
> expected but found "[".
>                                             ^
> "io.f90", Line = 2, Column = 44: ERROR: Unexpected syntax: "object-name"
> was expected but found "8".

Yes, It's a f2003 feature, sorry about that.  Try using:

     integer, parameter :: USR_UNIT(2) = (/ 6, 8 /)



Fri, 02 Jan 2009 23:24:55 GMT  
 writing output listing onto screen (or not) and onto file

Quote:


>>           Is it possible to simplify my code by putting only one
>> WRITE statement when I want to write output results onto screen
>> (or not) and onto a file :

> Are you asking about facilities provided by most systems for redirecting
> output sent to '*' (or, on many systems, unit 6 without an OPEN)?
> For example, the tee program, or redirection using '>' on the command line?

Your solution is good for me in the case I want to have results only on
a file.

In the other case I want to have results at the same time on the screen
and on a file!!

Thanks for your ansver

Bernard Bru



Fri, 02 Jan 2009 23:26:47 GMT  
 writing output listing onto screen (or not) and onto file
On Mon, 17 Jul 2006 08:15:09 -0700, bru wrote

Quote:
> Some time I want to have at the same time output on screen (Unit 6 or *)
> and onto a file (OPEN(8,FILE= 'sosout')
...
>>     integer, parameter :: USR_UNIT(2) = [6, 8]
>                                         ^
> "io.f90", Line = 2, Column = 40: ERROR: Unexpected syntax: "operand" was
> expected but found "[".

That's just because of the use of the [] for array constructors. That
is an f2003 feature adopted as an extension by some f95 compilers, but
you can't portably count on it in f95. But that is peripheral to the
question.

Quote:
> Your solution seems to me to heavy because I have hundred of writes in
> my code!!

Yes. I'd agree that this is a bit much for most applications. It
requires too much structuring of the code around this particular I/O
requirement.

If you want output to go to *EITHER* the terminal or a file, that is
relatively simple. There is a minor system-dependent piece needed to
get a unit number that is connected to standard output (f2003 finally
has a standard way to do this). Then you can select between that unit
or a unit connected to some other file. I do that kind of thing
regularly.

But if you want the output to go to both places, there isn't a "nice"
way to do that within Fortran. It requires that two WRITE statements be
executed. Something like the trick that jwm illustrated can be used to
make one statement that is executed twice, but still, the fundamental
issue is that there have to be two writes, whether written as two
separate statements, or as a single statement executed twice.

There are often ways outside of Fortran to do this. See the Unix "tee"
command (although sometimes it has "issues" with buffering, which can
cause awkwardness for interactive use.)

--
Richard Maine                     | Good judgment comes from
experience;
email: my first.last at org.domain| experience comes from bad judgment.
org: nasa, domain: gov            |       -- Mark Twain



Fri, 02 Jan 2009 23:36:03 GMT  
 writing output listing onto screen (or not) and onto file
Quote:


>>Some time I want to have at the same time output on screen (Unit 6 or *)
>>and onto a file (OPEN(8,FILE= 'sosout')

>>An an other time I want only output on file (here unit 8) (for me it is
>>easier to visualize the output using vim editor) So I put in this case
>>OPEN(6,FILE= 'NO') because I dont need it

> What about this:

>    integer, parameter :: USR_UNIT(2) = [6, 8]
>    integer i
>    logical StdOutput, FileOutput
>    real a, b, c

>    a = 1.; b = 2.; c = 3.

>    write(*, '("Std output? [T/F]: ")', ADVANCE = 'NO')
>    read(*, *) StdOutput

>    write(*, '("File? [T/F]: ")', ADVANCE = 'NO')
>    read(*, *) FileOutput

>    if (FileOutput) Open(unit = USR_UNIT(2), file = 'userfile.txt')

>    do i = 1, 2
>       if (i == 1 .AND. (.NOT.StdOutput)) cycle
>       if (i == 2 .AND. (.NOT.FileOutput)) cycle
>       write(USR_UNIT(i), "('  A B C=', 3F12.4)")  a, b, c
>    enddo

In my case your code is a little bit simpler with a test only on
StdOutput  :

    integer, parameter :: USR_UNIT(2) = (/6, 8/)
    integer i
    logical StdOutput
    real a, b, c

    a = 1.; b = 2.; c = 3.

    write(*, '("Std output? [T/F]: ")', ADVANCE = 'NO')
    read(*, *) StdOutput

    Open(unit = USR_UNIT(2), file = 'userfile.txt')

    do i = 1, 2
       if (i == 1 .AND. (.NOT.StdOutput)) cycle
       write(USR_UNIT(i), "('  A B C=', 3F12.4)")  a, b, c
    enddo
    end



Fri, 02 Jan 2009 23:45:41 GMT  
 writing output listing onto screen (or not) and onto file

[...snip example of selecting output units...]

Quote:
> Your solution seems to me to heavy because I have hundred of writes in
> my code!!

In priniciple, you could generalize jwm's example to any number of
units/files, but isolate the multiple WRITE's to a subroutine you've
written, e.g., MY_WRITE, and then replace all the WRITE's with
MY_WRITE's in your code.  Unfortunately in practice, that may be
quite difficult because of needing to pass a variable number of
arguments to MY_WRITE.  Only if the number of different combinations
of format, argument number and argument types is fairly small would
this be feasible (presumably be using a generic feature to overload
the finite number of different versions...).

    -Ken
--
I don't speak for Intel, Intel doesn't speak for me...

Ken Fairfield
D1C Automation VMS System Support
who:   kenneth dot h dot fairfield
where: intel dot com



Sat, 03 Jan 2009 04:57:45 GMT  
 writing output listing onto screen (or not) and onto file

Quote:


> [...snip example of selecting output units...]
> > Your solution seems to me to heavy because I have hundred of writes in
> > my code!!

> In priniciple, you could generalize jwm's example to any number of
> units/files, but isolate the multiple WRITE's to a subroutine you've
> written, e.g., MY_WRITE, and then replace all the WRITE's with
> MY_WRITE's in your code.  Unfortunately in practice, that may be
> quite difficult because of needing to pass a variable number of
> arguments to MY_WRITE.  Only if the number of different combinations
> of format, argument number and argument types is fairly small would
> this be feasible (presumably be using a generic feature to overload
> the finite number of different versions...).

How about using an internal WRITE first, then sending the resulting
string to a subroutine along with a flag value which selects where
output goes?

implicit none
character(len=256) :: s
integer :: i,j

open(7,file='out.txt')

i=10
j=20

write(s,*)i,j
call prt_sub(s,1)

i=i+10
j=j+20

write(s,*)i,j
call prt_sub(s,2)

i=i+10
j=j+20

write(s,*)i,j
call prt_sub(s,3)

end

subroutine prt_sub(s,f)
implicit none
character(*) :: s
integer :: f
  select case(f)
    case(1)
      write(*,*)trim(s)
    case(2)
      write(7,*)trim(s)
    case(3)
      write(*,*)trim(s)
      write(7,*)trim(s)
  end select
end

-- elliot



Sat, 03 Jan 2009 06:09:19 GMT  
 writing output listing onto screen (or not) and onto file

Quote:



> >>           Is it possible to simplify my code by putting only one
> >> WRITE statement when I want to write output results onto screen
> >> (or not) and onto a file :

> > Are you asking about facilities provided by most systems for redirecting
> > output sent to '*' (or, on many systems, unit 6 without an OPEN)?
> > For example, the tee program, or redirection using '>' on the command line?

> Your solution is good for me in the case I want to have results only on
> a file.

> In the other case I want to have results at the same time on the screen
> and on a file!!

> Thanks for your ansver

> Bernard Bru

Hi, Bernard.
Here is a module I wrote several years ago that I believe does what you
wish.  You first write your output line to a character variable (or
array), then call either log_message, log_screen, or log_abort, with
the variable (or array) as the argument.  log_message writes to the log
file only.  log_screen writes to both the log file and the user's
standard output stream, and log_abort writes to both the log file and
the standard error stream, then aborts program execution.

--Peter

MODULE logfile_mod
  ! This module contains variables and routines related
  !  to the log file.
  ! P. Simon
  ! Revised:  9 April 2003
  ! Revised:  27 June 2003, to use FPP/CPP directives supporting
  !                multiple platforms.
  !           NOTE: THIS FILE MUST BE COMPILED USING THE FPP
  !                      OR CPP PREPROCESSOR!

  CHARACTER(len=132)           :: logfile = 'arrayopt.log'
  INTEGER, PARAMETER        :: log_unit = 9 ! Unit number used
  !                                               ! for log messages.

  INTERFACE log_message
    MODULE PROCEDURE log_message_one
    MODULE PROCEDURE log_message_mult
  END INTERFACE

  INTERFACE log_screen
    MODULE PROCEDURE log_screen_one
    MODULE PROCEDURE log_screen_mult
  END INTERFACE

  INTERFACE log_abort
    MODULE PROCEDURE log_abort_one
    MODULE PROCEDURE log_abort_mult
  END INTERFACE

  PRIVATE       :: log_message_one
  PRIVATE       :: log_message_mult
  PRIVATE       :: log_screen_one
  PRIVATE       :: log_screen_mult
  PRIVATE       :: log_abort_one
  PRIVATE       :: log_abort_mult

CONTAINS

  SUBROUTINE log_message_one(msg,flushit)
    ! If necessary, open the log file, append a message to the end.
    ! Flush the buffer if flushit is present.

#ifdef _CVF
    USE dfport, ONLY: flush  ! Needed for Compaq Visual Fortran
#endif

    IMPLICIT NONE
    CHARACTER(len=*), INTENT(IN)      :: msg
    INTEGER, INTENT(IN), OPTIONAL     :: flushit
    LOGICAL                           :: op

    INQUIRE(unit=log_unit, opened=op)
    IF (.NOT. op) THEN
      OPEN(log_unit, file = logfile, status = 'unknown')
    END IF
    WRITE(log_unit,'(a)') TRIM(msg)
    IF (PRESENT(flushit)) CALL flush(log_unit)  ! Flush output buffer.
    RETURN
  END SUBROUTINE log_message_one

  SUBROUTINE log_message_mult(msg,flushit)
    ! If necessary, open the log file, append a message to the end.

#ifdef _CVF
    USE dfport, ONLY: flush  ! Needed for Compaq Visual Fortran
#endif

    IMPLICIT NONE
    CHARACTER(len=*), INTENT(IN)      :: msg(:)
    INTEGER, INTENT(IN), optional     :: flushit
    LOGICAL                           :: op
    INTEGER                           :: i

    INQUIRE(unit=log_unit, opened=op)
    IF (.NOT. op) THEN
      OPEN(log_unit, file = logfile, status = 'unknown')
    END IF
    DO i = 1, SIZE(msg)
      WRITE(log_unit,'(a)') TRIM(msg(i))
    END DO
    IF (PRESENT(flushit)) CALL flush(log_unit)  ! Flush output buffer.
    RETURN
  END SUBROUTINE log_message_mult

  SUBROUTINE log_screen_one(msg,flushit)
    ! If necessary, open the log file, append message to the end.
    ! Flush the buffer if flushit is present.  Send message to the
    ! screen, also.

#ifdef _CVF
    USE dfport, ONLY: flush  ! Needed for Compaq Visual Fortran
#endif

    IMPLICIT NONE
    CHARACTER(len=*), INTENT(IN)      :: msg
    INTEGER, INTENT(IN), OPTIONAL     :: flushit
    LOGICAL                           :: op

    INQUIRE(unit=log_unit, opened=op)
    IF (.NOT. op) THEN
      OPEN(log_unit, file = logfile, status = 'unknown')
    END IF
    WRITE(log_unit,'(a)') TRIM(msg)
    WRITE(*,'(a)') TRIM(msg)
    IF (PRESENT(flushit)) CALL flush(log_unit)  ! Flush output buffer.
    RETURN
  END SUBROUTINE log_screen_one

  SUBROUTINE log_screen_mult(msg,flushit)
    ! If necessary, open the log file, append a multiline
    ! message to the end.  Send message to users screen, also.

#ifdef _CVF
    USE dfport, ONLY: flush  ! Needed for Compaq Visual Fortran
#endif

    IMPLICIT NONE
    CHARACTER(len=*), INTENT(IN)      :: msg(:)
    INTEGER, INTENT(IN), optional     :: flushit
    LOGICAL                           :: op
    INTEGER                           :: i

    INQUIRE(unit=log_unit, opened=op)
    IF (.NOT. op) THEN
      OPEN(log_unit, file = logfile, status = 'unknown')
    END IF
    DO i = 1, SIZE(msg)
      WRITE(log_unit,'(a)') TRIM(msg(i))
      WRITE(*,'(a)') TRIM(msg(i))
    END DO
    IF (PRESENT(flushit)) CALL flush(log_unit)  ! Flush output buffer.
    RETURN
  END SUBROUTINE log_screen_mult

  SUBROUTINE log_abort_one(msg)
    ! If necessary, open the log file, append message to the end,
    ! abort program execution, after closing the log file.

#ifdef _CVF
    USE dfport, ONLY: abort  ! Needed for Compaq Visual Fortran
#endif

    IMPLICIT NONE
    CHARACTER(len=*), INTENT(IN)      :: msg
    LOGICAL                           :: op
    integer                           :: iunit

    INQUIRE(unit=log_unit, opened=op)
    IF (.NOT. op) THEN
      OPEN(log_unit, file = logfile, status = 'unknown')
    END IF
    DO iunit = 0, log_unit, log_unit-iunit
      WRITE(iunit,'(a)') ' '
      WRITE(iunit,'(a)') ' '
      WRITE(iunit,'(a)') '************* ABORTING EXECUTION
*************'
      WRITE(iunit,'(a)') TRIM(msg)
      WRITE(iunit,'(a)') '************* ABORTING EXECUTION
*************'
    END DO
    CLOSE(log_unit)  ! Finish
    CALL abort()
  END SUBROUTINE log_abort_one

  SUBROUTINE log_abort_mult(msg)
    ! If necessary, open the log file, append a multiline
    ! message to the end, then abort program execution,
    ! after closing the log file.

#ifdef _CVF
    USE dfport, ONLY: abort  ! Needed for Compaq Visual Fortran
#endif

    IMPLICIT NONE
    CHARACTER(len=*), INTENT(IN)      :: msg(:)
    LOGICAL                           :: op
    INTEGER                           :: i, iunit

    INQUIRE(unit=log_unit, opened=op)
    IF (.NOT. op) THEN
      OPEN(log_unit, file = logfile, status = 'unknown')
    END IF
    DO iunit = 0, log_unit, log_unit-iunit
      WRITE(iunit,'(a)') ' '
      WRITE(iunit,'(a)') ' '
      WRITE(iunit,'(a)') '************* ABORTING EXECUTION
*************'
      DO i = 1, SIZE(msg)
        WRITE(iunit,'(a)') TRIM(msg(i))
      END DO
      WRITE(iunit,'(a)') '************* ABORTING EXECUTION
*************'
    END DO
    CLOSE(log_unit)  ! Finish
    CALL abort()
  END SUBROUTINE log_abort_mult

END MODULE logfile_mod



Sat, 03 Jan 2009 07:05:23 GMT  
 writing output listing onto screen (or not) and onto file
Just define an interger*4 variable IOUNIT and set it to 0 for screen
output, or 2 (say) for printer or anything from 6 up (wiser) for a disk
device file..
The only problem is that screen i/o historically required a leading
space or other "carriage control" character as a prefix in the format
statement to avoid odd things happening, especially in earlier
compilers.
.
So you can work around the problem this way (one of many) by adding a
space only on screen i/o before any i/o to file IOUNIT..
    IF (iounit.eq.0) THEN
     write (0,701)
701 format(1X,\)
    ENDIF

Terence Wright



Sat, 03 Jan 2009 09:19:50 GMT  
 writing output listing onto screen (or not) and onto file
On Mon, 17 Jul 2006 18:19:50 -0700, Terry wrote

Quote:
> Just define an interger*4 variable IOUNIT

Default integer is better. There is no benefit to specifying the nonstandard
*4 here. That adds system dependence with no balancing benefit. Sometimes
there are good reasons for system dependence, but it is completely
superfluous here.

 and set it to 0 for screen

Quote:
> output, or 2 (say) for printer or anything from 6 up (wiser) for a disk
> device file..

Those numbers are compiler-dependent. In particular, the 0 is not
particularly universal. By far the most common number is that unit 6 is often
standard output.

Other aspects of the OP's question are addressed in other followups.

--
Richard Maine                    | Good judgement comes from experience;
email: last name at domain . net | experience comes from bad judgement.
domain: summertriangle           |  -- Mark Twain



Sat, 03 Jan 2009 10:30:50 GMT  
 writing output listing onto screen (or not) and onto file

Quote:



>>>           Is it possible to simplify my code by putting only one
>>> WRITE statement when I want to write output results onto screen
>>> (or not) and onto a file :

>> Are you asking about facilities provided by most systems for
>> redirecting output sent to '*' (or, on many systems, unit 6 without an
>> OPEN)?
>> For example, the tee program, or redirection using '>' on the command
>> line?

> Your solution is good for me in the case I want to have results only on
> a file.

> In the other case I want to have results at the same time on the screen
> and on a file!!

Given that you have a bunch of these writes in your code already, a solution that uses
your O/S might be quicker. E.g. in *nix, for output to a file only, you do the usual redirect,

   myprog > log_file

For output to a file and stdout you can use the "tee" utility,

   myprog | tee log_file

Your previous posts indicate you're running on linux and/or unix systems so this is a
quick fix - with zero modification of your source code.

If you want duplicated output in the source code itself, then it really should be done
properly -- similar to what a previous poster, Peter, suggested. I've done similar and it
works great but it really needs to be built in from the start (IMO).

cheers,

paulv

--
Paul van Delst             Ride lots.

Ph: (301)763-8000 x7748
Fax:(301)763-8545



Sat, 03 Jan 2009 23:20:52 GMT  
 
 [ 17 post ]  Go to page: [1] [2]

 Relevant Pages 

1. How to write a file onto sub-folder from htdocs (TCL-Apache1.3-Win2K)

2. Clock onto screen

3. Screen copied text onto command line means nothing

4. SICP: not hanging onto streams

5. Register onto the INFO-ADA Mail List

6. Dropping files onto apps

7. Dropping folder of files onto RB application

8. Dropping files onto the app icon?

9. How to upload a file onto a webpage using LabVIEW FTP server

10. placing a picture file onto a graph

11. Drag files onto a Tk application

12. dragging a file onto a tcl script...

 

 
Powered by phpBB® Forum Software