Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

print new line after unlimited format

198 views
Skip to first unread message

Beliavsky

unread,
Jan 19, 2021, 7:46:39 PM1/19/21
to
Is there a way to print an arbitrary number of integers followed by a new line,
using a single statement? If you know how many integers are printed, it is possible, as shown in the second line of code.

write (*,"(*(1x,i0),/)") 5,10 ! no new line after printing
write (*,"(2(1x,i0),/)") 5,10 ! new line after printing
write (*,"(a)") "hello"
end

gah4

unread,
Jan 19, 2021, 9:40:30 PM1/19/21
to
You should get a newline after printing, but it seems that you want
an extra newline. Is this for some statement minimizing contest?

Note that:

write(*,*)

will get you the extra newline, so it isn't all that complicated, but
it is a separate statement. The complicated solution is to generate
a run-time format in a CHARACTER variable, and sometimes that is needed
(and also takes two statements).

But okay, if you want to put it into an IF statement, then you need
the extra lines to get two statements in.

Arjen Markus

unread,
Jan 20, 2021, 2:31:34 AM1/20/21
to
On Wednesday, January 20, 2021 at 3:40:30 AM UTC+1, gah4 wrote:
> On Tuesday, January 19, 2021 at 4:46:39 PM UTC-8, Beliavsky wrote:
> > Is there a way to print an arbitrary number of integers followed by a new line,
> > using a single statement? If you know how many integers are printed, it is possible, as shown in the second line of code.
>
> > write (*,"(*(1x,i0),/)") 5,10 ! no new line after printing
...

Why not use:

write(*,'(*(1x,i0),/,a)') array_of_ints, '' ! Add an empty string at the end to force the evaluation of the entire format string

Regards,

Arjen

James Van Buskirk

unread,
Jan 20, 2021, 2:58:56 AM1/20/21
to
"Beliavsky" wrote in message
news:aa8503fe-c942-4227...@googlegroups.com...
D:\gfortran\clf\newline_test>type newline_test.f90
program newline_test
implicit none
write(*,'(*(g0))') 'Test output follows:'
write(*,'(*(1x,g0))') 5, 10, new_line('a')
write(*,'(*(g0))') 'Did we get an extra new line?'
end program newline_test

D:\gfortran\clf\newline_test>gfortran newline_test.f90 -onewline_test

D:\gfortran\clf\newline_test>newline_test
Test output follows:
5 10

Did we get an extra new line?

Ron Shepard

unread,
Jan 20, 2021, 3:41:54 AM1/20/21
to
On 1/19/21 6:46 PM, Beliavsky wrote:
[...]
How about:

write (*,"(*(1x,i0))") 5,10
write (*,"(/a)") "hello"
end

Beliavsky

unread,
Jan 20, 2021, 7:38:04 AM1/20/21
to
Thanks. I need to use the g edit descriptor more. It is very flexible.

Beliavsky

unread,
Jan 20, 2021, 10:33:29 AM1/20/21
to
That does not work with Intel or gfortran, which says at run time

At line 1 of file xunlim.f90 (unit = 6, file = 'stdout')
Fortran runtime error: Expected INTEGER for item 1 in formatted transfer, got REAL
(*(1x,i0),/,a)
^

Error termination. Backtrace:

Arjen Markus

unread,
Jan 20, 2021, 10:42:19 AM1/20/21
to
On Wednesday, January 20, 2021 at 4:33:29 PM UTC+1, Beliavsky wrote:
Oh, that is a pity - I had not realised that the unlmited format would consume ALL items! Well, that makes sense. So, if you use an unlimited format group, it has to be the last one in the format string. With g0 the problem is solved in a better way.

Ron Shepard

unread,
Jan 20, 2021, 11:44:23 AM1/20/21
to
Just out of curiosity, how portable is this? For example, on MS
operating systems, new records are delimited with the two-character
sequence <cr><lf>. What happens if a single <lf> character appears in
the middle of a record?

$.02 -Ron Shepard


Beliavsky

unread,
Jan 20, 2021, 12:39:10 PM1/20/21
to
JvB's program compiled with gfortran runs the same on Windows and Windows Subsystem for Linux, except that on Windows there a blank line before the cursor when run from the console. On WSL there is not. A program print*,"hi" ; end also exhibits this difference between Windows and WSL. To get "Hello, World" without a blank line on Windows one needs

write (*,"(a)",advance="no") "Hello, World"

gah4

unread,
Jan 20, 2021, 4:01:36 PM1/20/21
to
On Wednesday, January 20, 2021 at 8:44:23 AM UTC-8, Ron Shepard wrote:

(snip)

> >> write(*,'(*(1x,g0))') 5, 10, new_line('a')

(snip)

> Just out of curiosity, how portable is this? For example, on MS
> operating systems, new records are delimited with the two-character
> sequence <cr><lf>. What happens if a single <lf> character appears in
> the middle of a record?

That is a good question. The way it works in C, is that programs write
out '\n', which is usually called the newline character, but in any case is
a single character. The I/O library then figures out what to do to make it
work on the given system. It turns out that on Unix and unix-like systems
it just writes out the character. On DOS/Windows and related systems
it converts to the two character termination sequence on output, and
back again on input. Some IBM systems store lines with a length prefix,
so the library has to translate to/from that. (There are some complications
with ftell() and fseek() related to this conversion.)

Since many Fortran libraries now use the C library to do actual I/O,
that naturally happens. As well as I know, the standard is written
to make that obvious, but I never tried to be sure. In any case, it
is my preference not to write them that way.

Reminds me, in Fortran 66 days on IBM systems, I once had a character
constant with a newline character in it. I am not sure now why I
didn't use a hex constant. It was slightly tricky to get the character in.
(EBCDIC is interesting in that there are CR, LF, and NL as three different
characters, but only two in ASCII.)


Gary Scott

unread,
Jan 20, 2021, 8:50:38 PM1/20/21
to
On 1/20/2021 3:01 PM, gah4 wrote:
> On Wednesday, January 20, 2021 at 8:44:23 AM UTC-8, Ron Shepard wrote:
>
> (snip)
>
>>>> write(*,'(*(1x,g0))') 5, 10, new_line('a')
>
> (snip)
>
>> Just out of curiosity, how portable is this? For example, on MS
>> operating systems, new records are delimited with the two-character
>> sequence <cr><lf>. What happens if a single <lf> character appears in
>> the middle of a record?
>
> That is a good question. The way it works in C, is that programs write
> out '\n', which is usually called the newline character, but in any case is
> a single character. The I/O library then figures out what to do to make it
> work on the given system. It turns out that on Unix and unix-like systems
> it just writes out the character. On DOS/Windows and related systems
> it converts to the two character termination sequence on output, and
> back again on input. Some IBM systems store lines with a length prefix,
> so the library has to translate to/from that. (There are some complications
> with ftell() and fseek() related to this conversion.)

Current versions of VM allow you to mix support for "byte files" with
native files. I forget the details. I considered transalating some of
my mainframe (CMS) interactive graphics tools to support byte files for
easier translation to other systems, but we transitioned off before I
finished.

Arjen Markus

unread,
Jan 21, 2021, 2:56:09 AM1/21/21
to
On Wednesday, January 20, 2021 at 10:01:36 PM UTC+1, gah4 wrote:

> That is a good question. The way it works in C, is that programs write
> out '\n', which is usually called the newline character, but in any case is
> a single character. The I/O library then figures out what to do to make it
> work on the given system. It turns out that on Unix and unix-like systems
> it just writes out the character. On DOS/Windows and related systems
> it converts to the two character termination sequence on output, and
> back again on input. Some IBM systems store lines with a length prefix,
> so the library has to translate to/from that. (There are some complications
> with ftell() and fseek() related to this conversion.)
>
On Windows there is some subtlity awaiting in the wings: if you use Cygwin to build your programs, it may simply write a line feed character as the end (IIRC it is an install option), but with MinGW the program would write a carriage return - line feed combination. And of course, you can run the Cygwin version in an ordinary command window, as long as you set the path right.

Regards,

Arjen

Ev. Drikos

unread,
Jan 21, 2021, 7:16:05 AM1/21/21
to
On 20/01/2021 23:01, gah4 wrote:
> On Wednesday, January 20, 2021 at 8:44:23 AM UTC-8, Ron Shepard wrote:
>
> (snip)
>
>>>> write(*,'(*(1x,g0))') 5, 10, new_line('a')
>
> (snip)
>
>> Just out of curiosity, how portable is this? For example, on MS
>> operating systems, new records are delimited with the two-character
>> sequence <cr><lf>. What happens if a single <lf> character appears in
>> the middle of a record?
>
> That is a good question. The way it works in C, is that programs write
> out '\n', which is usually called the newline character, but in any case is
> a single character. The I/O library then figures out what to do to make it
> work on the given system. It turns out that on Unix and unix-like systems
> it just writes out the character. On DOS/Windows and related systems
> it converts to the two character termination sequence on output, and
> back again on input. Some IBM systems store lines with a length prefix,
> so the library has to translate to/from that. (There are some complications
> with ftell() and fseek() related to this conversion.)
>
> ...

Just for the record, in Java one can use


Ev. Drikos

unread,
Jan 21, 2021, 7:17:47 AM1/21/21
to
Just for the record, in Java one can use a portable way. I think ie:

System.getProperty("line.separator");

Robin Vowels

unread,
Jan 21, 2021, 7:46:43 AM1/21/21
to
On Wednesday, January 20, 2021 at 11:46:39 AM UTC+11, Beliavsky wrote:
> Is there a way to print an arbitrary number of integers followed by a new line,
> using a single statement? If you know how many integers are printed, it is possible, as shown in the second line of code.
>
> write (*,"(*(1x,i0),/)") 5,10 ! no new line after printing
.
After every WRITE statement, the next output will start on a new line.
(This can change if ADVANCE="NO" is specified.)
The "/" has no effect in this statement because format control does
not get beyond the ")" that follows i0.
.
> write (*,"(2(1x,i0),/)") 5,10 ! new line after printing
.
That's because the format 1x,i0 is used twice, and format control
then moves on to process the '/'.
.

Robin Vowels

unread,
Jan 21, 2021, 7:52:44 AM1/21/21
to
.
This won't work, because format control keeps reverting to the start of the format
1x,i0 every time it encounters the ')' that follows i0.
Thus, when the list of integers is exhausted, the null string
is matched to i0, which causes an I/O error.

Ev. Drikos

unread,
Jan 21, 2021, 10:34:13 AM1/21/21
to
On 21/01/2021 09:56, Arjen Markus wrote:
> On Wednesday, January 20, 2021 at 10:01:36 PM UTC+1, gah4 wrote:
>
>> ...
>>
> On Windows there is some subtlity awaiting in the wings: if you use Cygwin to build your programs, it may simply write a line feed character as the end (IIRC it is an install option), but with MinGW the program would write a carriage return - line feed combination. And of course, you can run the Cygwin version in an ordinary command window, as long as you set the path right.
> ...

Hello,

Maybe CygWin supports some installation option, not sure. In any
case one could possibly examine an environment variable at runtime,
ie PATH or PWD, and if the first character is a '/' then assume
Linux settings ('\n' for new line & '-' as command option prefix).
Otherwise, one may assume Win settings ('\r\n' & '/' respectively).

In other environments these strings are known at compile time. So
one can avoid the runtime overhead (if it's a problem). In my case,
a C++ project I build determines that prefix this way because CygWin
was the last porting environment (I was using a C preprocessor :-).

There is more than that however. In a Power Shell, I also call this:

SetConsoleOutputCP(65001)

So, I've also utf-8 characters rendered properly. What's next? Just
made a simple test with a Fortran program that prints 6 lines. The
same executable prints new lines with a '\n' inside CygWin and
Notepad displays the output in one line. Whereas in a Power Shell
Console the same executable prints new lines with an '\r\n' and
Notepad displays the output in six lines. This seems to be ok!

Of course, I don't doubt that one may possibly face other issues.


Ev. Drikos

gah4

unread,
Jan 21, 2021, 7:47:37 PM1/21/21
to
On Wednesday, January 20, 2021 at 5:50:38 PM UTC-8, Gary Scott wrote:

(snip, I wrote)
> > Some IBM systems store lines with a length prefix,
> > so the library has to translate to/from that. (There are some complications
> > with ftell() and fseek() related to this conversion.)

> Current versions of VM allow you to mix support for "byte files" with
> native files. I forget the details. I considered transalating some of
> my mainframe (CMS) interactive graphics tools to support byte files for
> easier translation to other systems, but we transitioned off before I
> finished.

For text files, because of the complication of newline characters, the
C library only defines using fseek() for values returned by ftell().

In the case of VB (variable length blocked record) files, OS/360 and
successors only keep track of blocks and offsets into blocks.
The traditional CMS file system emulates that. One C library
uses 32768*block+offset as the ftell()/fseek() value.

I don't think I ever wrote C for VM, but used to have the manuals
for it.

gah4

unread,
Jan 21, 2021, 7:53:58 PM1/21/21
to
On Tuesday, January 19, 2021 at 4:46:39 PM UTC-8, Beliavsky wrote:
> Is there a way to print an arbitrary number of integers followed by a new line,
> using a single statement?

This is the opposite problem I remember having often enough
in the Fortran 66 days.

Stream I/O in C and other languages conveniently allows more than one
statement to generate output for a line. There are some things that are
very difficult to format otherwise. Some that can be done using internal I/O,
either to generate character values to write, or format strings to use.
(And which goes back to the record oriented file systems of early
Fortran machines.)

The addition of non-advancing I/O makes those problems easier.
There is some overhead for each I/O statement, but it should be
small enough not to worry about. Why the need for only one
statement?

dave_th...@comcast.net

unread,
Feb 28, 2021, 10:54:59 PM2/28/21
to
On Thu, 21 Jan 2021 17:34:10 +0200, "Ev. Drikos" <drik...@gmail.com>
wrote:

> On 21/01/2021 09:56, Arjen Markus wrote:
...
> made a simple test with a Fortran program that prints 6 lines. The
> same executable prints new lines with a '\n' inside CygWin and
> Notepad displays the output in one line. Whereas in a Power Shell
> Console the same executable prints new lines with an '\r\n' and
> Notepad displays the output in six lines. This seems to be ok!
>
_Windows 10_ notepad correctly handles both CRLF and LF files, but
earlier versions don't. _wordpad_ handles both at least since XP.
Many third-party editors (like notepad++) handle both. When writing to
a file the powershell/console codepage usually doesn't matter, only
when writing to the console.

Ev. Drikos

unread,
Mar 1, 2021, 3:14:20 AM3/1/21
to
On 01/03/2021 05:55, dave_th...@comcast.net wrote:
> On Thu, 21 Jan 2021 17:34:10 +0200, "Ev. Drikos" <drik...@gmail.com>
> wrote:
>
>> On 21/01/2021 09:56, Arjen Markus wrote:
> ...
>> made a simple test with a Fortran program that prints 6 lines. The
>> same executable prints new lines with a '\n' inside CygWin and
>> Notepad displays the output in one line. Whereas in a Power Shell
>> Console the same executable prints new lines with an '\r\n' and
>> Notepad displays the output in six lines. This seems to be ok!
>>
> _Windows 10_ notepad correctly handles both CRLF and LF files, but
> earlier versions don't...

I should had said that I was testing in Windows-8.1

Thanks

0 new messages