[comp.lang.fortran] WRITE don't do that too me!

quan@sol.surv.utas.oz (Stephen Quan) (09/11/90)

I am really a C fan, but I must say, over the couple of months programming in
FORTRAN, I am beginning to enjoy it a bit.  Anyway, I have a nagging problem
that has lasted since I have started and was wondering if any of you FORTRAN
gurus knew a simple (standard) FORTRAN method to do the following.

Essentially, I am looking for the putchar(x) C-equivalent where x may be any
character.  I got close using (if I recall correctly) :

eg. putchar(27) is almost :
	INTEGER I
	CHARACTER X
	EQUIVALENCE (I,X)
	X = 27
	WRITE (*,100) X
100     FORMAT(A1)

However, this isn't quite the same as putchar(c) because the WRITE command
also adds a NEWLINE character, how can I suppress the NEWLINE character?
The interest here, is that I'm trying to write some graphics routines in
FORTRAN.  At the moment, the only solution I can see is to store the codes
into a string of some kind and output the string when a NEWLINE would be
safe to output.

Also, another question (about standard), in FORTRAN is it standard to have
all commands in upper case.  Recently, in maintaining somebody elses code, I
changed the whole lot to lower case, the compiler accepted it, but then I
compiled using the ANSI-<whatever> mode and it gave errors indicating that
I was not within the standard.  Does the standard insist on uppercase
characters?

Stephen Quan.  (quan@sol.surv.utas.edu.au)
School of Surveying.
University of Tasmania.

chidsey@smoke.BRL.MIL (Irving Chidsey) (09/11/90)

In article <quan.653053983@sol> quan@sol.surv.utas.oz (Stephen Quan) writes:
<I am really a C fan, but I must say, over the couple of months programming in
<FORTRAN, I am beginning to enjoy it a bit.  Anyway, I have a nagging problem
<that has lasted since I have started and was wondering if any of you FORTRAN
<gurus knew a simple (standard) FORTRAN method to do the following.
<
<Essentially, I am looking for the putchar(x) C-equivalent where x may be any
<character.  I got close using (if I recall correctly) :
<
<eg. putchar(27) is almost :
<	INTEGER I
<	CHARACTER X
<	EQUIVALENCE (I,X)
<	X = 27
<	WRITE (*,100) X
<100     FORMAT(A1)
<
<However, this isn't quite the same as putchar(c) because the WRITE command
<also adds a NEWLINE character, how can I suppress the NEWLINE character?
<The interest here, is that I'm trying to write some graphics routines in
<FORTRAN.  At the moment, the only solution I can see is to store the codes
<into a string of some kind and output the string when a NEWLINE would be
<safe to output.

	No NEWLINE is an extension to the standard.  On our Convex a $ 
is what supresses NEWLINEs.
<
<Also, another question (about standard), in FORTRAN is it standard to have
<all commands in upper case.  Recently, in maintaining somebody elses code, I
<changed the whole lot to lower case, the compiler accepted it, but then I
<compiled using the ANSI-<whatever> mode and it gave errors indicating that
<I was not within the standard.  Does the standard insist on uppercase
<characters?
<
	lower case is also an extension to the standard.  I believe it is
a popular extension.

<Stephen Quan.  (quan@sol.surv.utas.edu.au)
<School of Surveying.
<University of Tasmania.

							Irv

-- 
I do not have signature authority.  I am not authorized to sign anything.
I am not authorized to commit the BRL, the DOA, the DOD, or the US Government
to anything, not even by implication.
			Irving L. Chidsey  <chidsey@brl.mil>

maine@elxsi.dfrf.nasa.gov (Richard Maine) (09/12/90)

On 11 Sep 90 14:58:08 GMT, chidsey@smoke.BRL.MIL (Irving Chidsey) said:

Irving> In article <quan.653053983@sol> quan@sol.surv.utas.oz (Stephen Quan)..

Stephen> how can I suppress the NEWLINE character?...
Stephen> At the moment, the only solution I can see is to store the codes
Stephen> into a string of some kind and output the string when a NEWLINE would
Stephen> be safe to output.

That's a very good and safe approach.  It is also likely to be good
for efficiency.  On many operating systems, something about like that
happens anyway, though it may be "behind your back".

Irving> 	No NEWLINE is an extension to the standard.  On our Convex a $ 
Irving> is what supresses NEWLINEs.

As Irving says, it is an extension.  It is a fairly common one, but not
universal by any means.  Note that Fortran 90 does include a simillar
concept as standard.  (It's called non-advancing I/O there).

Stephen> Does the standard insist on uppercase characters?

Irving> lower case is also an extension to the standard.  I believe it is
Irving> a popular extension.

The standard allows only one case (usually interpreted as upper case,
though it's not quite explicitly stated).  However, allowing both
cases is an extension so common as to be almost universal.  The only
exceptions I have seen for a long time have been on machines that
don't have both cases in their hardware character set.  The process of
transferring ASCII (or EBCDIC) source code to such machines usually
handles the case conversion automatically anyway.

Thus it's awfully hard to get in trouble using mixed case as long as
you do not use the C abomination (oops, sorry about the religion)
of using case to distinguish otherwise identically spelled variables.

Note here also that mixed case is "sanctioned" by the Fortran 90
standard.  It is not required that all compilers support two cases
(hard to do on systems with 6 bit characters), but it is sanctioned.
The Fortran 90 standard specifies that two variable names differing
only in case refer to the same variable.  (I'm paraphrasing here).

--
--

Richard Maine
maine@elxsi.dfrf.nasa.gov [130.134.64.6]

whit@milton.u.washington.edu (John Whitmore) (09/12/90)

In article <quan.653053983@sol> quan@sol.surv.utas.oz (Stephen Quan) writes:
>
>Essentially, I am looking for the putchar(x) C-equivalent where x may be any
>character.  I got close using (if I recall correctly) :
>
>eg. putchar(27) is almost :
>	INTEGER I
>	CHARACTER X
>	EQUIVALENCE (I,X)
>	X = 27
>	WRITE (*,100) X
>100     FORMAT(A1)
>
>However, this isn't quite the same as putchar(c) because the WRITE command
>also adds a NEWLINE character, how can I suppress the NEWLINE character?

	Using '*' output unit means you have to accept the FORM='FORMATTED'
nature of its implicit OPEN statement; if instead you OPEN explicitly

	OPEN(UNIT=NGRAPH, FORM='UNFORMATTED'...)

it should be just as easy to
	
	WRITE(NGRAPH) CHAR(27)

as to do the C-equivalent 'putchar(27)'.  I prefer to use the CHAR
function, as it might be difficult to EQUIVALENCE character with
other data types (i.e. generally impossible).
	As nearly as I can determine, unformatted output does NOT
add any <CR> or <LF>; you might run into some other record terminations,
though, and the OPEN might have to be given some machine-dependent
guidance in order to route the output to 'standard output'.

		John Whitmore

ok@goanna.cs.rmit.oz.au (Richard A. O'Keefe) (09/12/90)

In article <quan.653053983@sol>, quan@sol.surv.utas.oz (Stephen Quan) writes:
> that has lasted since I have started and was wondering if any of you FORTRAN
> gurus knew a simple (standard) FORTRAN method to do the following.

> 	INTEGER I
> 	CHARACTER X
> 	EQUIVALENCE (I,X)

Equivalencing character and non-character data is *not* defined by
the standard.  A standard-conforming program cannot do this.

If you are using BSD UNIX, that Fortran library has
	integer function putc(char)
	    character*1 char
and
	integer function fputc(iunit, char)
	    integer iunit
	    character*1 char
which do exactly what you want, except for working with characters.
Given an integer I, to write it out using putc(), just do
	putc(char(I))

If you haven't got putc() in your Fortran library, it only takes a few
lines of code to set up a common block with a character array and a
counter and thus define your own putc().  (Mine takes 32 lines, without
using 'include'.)

-- 
Heuer's Law:  Any feature is a bug unless it can be turned off.

maine@elxsi.dfrf.nasa.gov (Richard Maine) (09/12/90)

On 12 Sep 90 01:08:38 GMT, whit@milton.u.washington.edu (John Whitmore) said:

John> 	As nearly as I can determine, unformatted output does NOT
John> add any <CR> or <LF>; you might run into some other record terminations,
                                ^^^^^
John> though, and the OPEN might have to be given some machine-dependent
John> guidance in order to route the output to 'standard output'.

You are *guaranteed* to run into some form of record termination or
record header or some other machine-dependent record structure in most
cases.  This is essentially required by the standard for sequential
i/o, regardless of whether it is formatted or unformatted, because the
standard allows a program to write variable length records and then
to later skip over them by reading only part of each record.

The only cases where the standard allows any hope of avoiding record
terminators is with access='direct', in which case the records are
fixed length.  Even here, the standard does not forbid machine-dependent
record structure, and some machines do have such.  This has been
discussed here before, so I'll avoid further elaboration.

Vendor-dependent extensions are another question entirely.  Yes, they
exist.  No, they are not completely portable.

--

Richard Maine
maine@elxsi.dfrf.nasa.gov [130.134.64.6]

whit@milton.u.washington.edu (John Whitmore) (09/13/90)

In article <MAINE.90Sep12075420@altair.dfrf.nasa.gov> maine@elxsi.dfrf.nasa.gov (Richard Maine) writes:
>On 12 Sep 90 01:08:38 GMT, whit@milton.u.washington.edu (John Whitmore) said:
>
>John> 	As nearly as I can determine, unformatted output does NOT
>John> add any <CR> or <LF>; you might run into some other record terminations,
>                                ^^^^^
>
>You are *guaranteed* to run into some form of record termination or
>record header or some other machine-dependent record structure in most
>cases.
	
	Well, I read the original post as inquiring how output could
be created that would properly tweak a smart (graphics) terminal
with the correct bytes (and not pad it with extraneous fluff).
At least on VMS, the 'record structure' is entirely subsumed
in some header information, and WRITEing records, or COPYing a file, to 
a terminal port doesn't bother with any transferrence of that header
material.  Yes, there was record-length information in a
permanent file created; no, that record-length information did NOT
show up in the byte stream to the terminal.  The I/O driver
for the serial port is apparently smart in this regard.  As
you say, this may not be universally true.
>
>The only cases where the standard allows any hope of avoiding record
>terminators is with access='direct', in which case the records are
>fixed length.

	Thanks for pointing this out; I had thought RECORDTYPE='FIXED'
was a standard feature of OPEN, which I now see is not the case.

                 	John Whitmore

jerry@violet.berkeley.edu (Jerry Berkman) (09/23/90)

In article <quan.653053983@sol> quan@sol.surv.utas.oz (Stephen Quan) writes:
>Essentially, I am looking for the putchar(x) C-equivalent where x may be any
>character.  I got close using (if I recall correctly) :

>eg. putchar(27) is almost :
>	INTEGER I
>	CHARACTER X
>	EQUIVALENCE (I,X)
>	X = 27
>	WRITE (*,100) X
>100    FORMAT(A1)

>However, this isn't quite the same as putchar(c) because the WRITE command
>also adds a NEWLINE ... I'm trying to write some graphics routines in
>FORTRAN.

>Stephen Quan.  (quan@sol.surv.utas.edu.au)

On BSD VAX UNIX systems, and probably others, there are Fortran callable
routines:
	ierr =  putc(ch)
	ierr =  fputc(iunit,ch)
Also, as I recall, there was a bug in the BSD f77 library which deleted
any null characters written with 'a' formats.  I'm not sure how long ago
it was fixed, but it's probably still around in at least a few  systems
which copied the source to the libraries before the fix, or in systems
never updated.

	- Jerry Berkman, U.C.Berkeley, (415)642-4804
	  jerry@violet.berkeley.edu

disclaimer:
	opinions are my own, not my employers, etc.