1
votes

As a part of a larger program, written in the new Fortran standard, I am interested to write some text on a file that will be read by another program over which I have no control. Long ago when I learned Fortran an output record generated by a format statement should begin with an LF (linefeed) and end with a CR (carriage return). This means that each output record should be separated by a sequence CRLF.

To my surprise I find that this seems no longer to be true except when I compile and run my program on a Windows computer. When I compile and run my program on a Mac the output records are separated by a single LF. I know this is a Linux standard but I guess I assumed the output from a Fortran program should not depend on the operating system.

The consequence of this is that when I generate the output on Windows my output file can be read by the other program (which only exists on Windows) whereas when I generate the same output on my Mac it fails. I have no idea how the other program reads the file but I assume it is a standard Fortran read.

I have also compared my output file from Windows and Mac using "diff" and that indicates all lines are different. However "diff -w" indicates the files are identical.

I would like to be able to generate output that can be read by the other program independently if I generate the file on a Mac or Windows. I know I can use things like #ifdef to check the OS when I compile but I wonder if there is any other way, are there some option in the Fortran write? I know there are a lot of new things line "noadvance" etc. Any option to force a "CRLF" record separator?

I use GNU Fortran version 5.2 on Windows and what seems to be called version 7.2 on the Mac

1
That has never been true. That must have been a feature of a particular compiler on some particular platform. - Vladimir F
You can always convert the files by unix2dos. But the thing to really blame is the external program. It is at fault that it does not understand normal unix text files. But I understand you have to work with what you have. - Vladimir F
Program to the lowest common denominator - Windows. Then, if you are subsequently lucky enough to have a superior OS like macOS or Linux, you will have the tools (such as dos2unix) at your disposal to carry on working. - Mark Setchell
With Intel Fortran you can set the RECORDTYPE environment variable. But I don't know of anything like that for gfortran. - Vladimir F
@MarkSetchell The point is Fortran puts the record markers automatically. In different ways in Windows and in Linux. And even more differently on record-oriented platforms. - Vladimir F

1 Answers

0
votes

According to the documentation, gfortran allows a peculiar flag for the OPEN statement, called CARRIAGECONTROL, as in:

program prg

    integer :: u

    open (newunit = u, file = 'test.txt', carriagecontrol = 'fortran')

    write (u, '(A,I2)') '-', 12
    write (u, '(A,I2)') '-', 34

    close (u)

end program prg

This option is only supported when the code is compiled with the -fdec switch. The content of the output file is then:

> hexdump -C test.txt
00000000  0a 31 32 0d 0a 33 34 0d                           |.12..34.|
00000008

which is exactly the format that you described. The minus signs in the I/O lists in the above code are consumed by the compiler runtime library and used to redefine the output format. (Tested with gfortran 9.2.)