writing output listing onto screen (or not) and onto file
Author |
Message |
Bernard Br #1 / 17
|
 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 |
|
 |
Tim Princ #2 / 17
|
 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 |
|
 |
bru #3 / 17
|
 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 |
|
 |
jwm #4 / 17
|
 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 |
|
 |
bru #5 / 17
|
 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 |
|
 |
jwm #6 / 17
|
 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 |
|
 |
bru #7 / 17
|
 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 |
|
 |
Richard Main #8 / 17
|
 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 |
|
 |
bru #9 / 17
|
 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 |
|
 |
Ken Fairfiel #10 / 17
|
 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 |
|
 |
e p chandle #11 / 17
|
 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 |
|
 |
Pete #12 / 17
|
 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 |
|
 |
Terr #13 / 17
|
 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 |
|
 |
Richard Main #14 / 17
|
 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 |
|
 |
Paul Van Dels #15 / 17
|
 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 |
|
|
Page 1 of 2
|
[ 17 post ] |
|
Go to page:
[1]
[2] |
|