Append a record to the end of a text file: Difference between revisions

→‎{{header|Fortran}}: rephrase somewhat.
(→‎{{header|Java}}: code cleanup, consistent indentation)
(→‎{{header|Fortran}}: rephrase somewhat.)
Line 769:
 
=={{header|Fortran}}==
Prior to F90, data aggregates can't be defined so one would use an assemblage of variables (perhaps with similar names) ratherand thanbe diligent over every READ and WRITE statement naming them all and in the right order. With F90 the assemblage can be declared via a single name such as NOTE which has subcomponents, if defined via repeated use of TYPE. In COBOL and pl/i, the definition of an aggregate can be done more smoothly. A further difficulty is that character variables have a fixed size, and there is no length field to allow a "string" style usage. Fortran 2003 formalised a scheme whereby character variables can be re-allocated with a suitable size on assignment so that for example <code>NOTE.ACCOUNT = "Fred"</code> would regenerate the variable as a four-character text until it was next assigned to, and there would be no trailing spaces as there are when the variable's length is fixed at 28. However, when written, there is no indication of the actual length of such a variable.
 
WhenIn the absence of a length indication, when outputting text variables with a view to having them read in again, delimiting them with quotes (and doubling internal quotes) is the route to peace of mind, because otherwise a text might contain a comma as in "43 Gurney Road, Belmont" and in the absence of quoting, such a sequence on input might well be taken as two fields rather than one and a mess is certain. This facility is offered by the free-format (or, "list directed") style initiated by the use of * in place of a format label, as in <code>WRITE (MSG,*) ''etc.''</code>, provided however that the output file has been opened with the optional usage attribute <code>DELIM = "QUOTE"</code>, an unfortunate choice of name, because the field separator character could also be termed a "delimiter" and the default value is both a space or comma, when often what is preferable is only a comma, or even a tab. But there is no standard method to specify this desire. Only if the texts never themselves contain commas or spaces will this free-format scheme evade extra effort, and the specified example precludes this simplicity.
 
The resulting output is strung along an output line, with a default line length of 132 (a standard lineprinter width); the specification of RECL = 666 ensures that all the output fields are rolled to one line - that isn't padded out to 666 characters: this is not a fixed-length record despite the specification of RECL as a constant. Unfortunately, the trailing spaces in each character variable are rolled forth and there is no option along the lines of <code>WRITE (MSG,*) TRIM(NOTE)</code> One could instead use a suitable FORMAT statement with "A" format codes, but every element of NOTE would have to be named in the output list and the TRIM function applied only to each character field. Not only would this be tedious and error-prone, there would beis no format code for the enquoting and double-quoting of the texts and thus, no peace of mind... One would of course devise a subroutine to write out such a record (which would probably be more complex, with the FULLNAME subdivided, etc.), but the task's main objective is to demonstrate appending output to a file.<lang Fortran> PROGRAM DEMO !As per the described task, more or less.
TYPE DETAILS !Define a component.
CHARACTER*28 FULLNAME
Line 885:
NOTE%SHELL = "/bin/bash "
/</pre>
Because the output file (MSG) was opened with DELIM="QUOTE", the text variables are presented enquoted. This makes it clear whether fields have leading spaces or not, which with the usual proportionally-spaced typefaces and .html rendering is not clear in the example and could cause serious difficulty in practice as between "Joe Bloggs" and " Joe Bloggs". Because the DELIM feature also applies to both free-format and namelist output, <code>WRITE (MSG,*) "Record",N</code> would produce output with the text "Record" in quotes, so instead a suitable FORMAT statement is used. Alas, for compound names the % symbol is used instead of a period, a pity. NAMELIST style I/O starts with "&STUFF" (the name of the NAMELIST) and ends with "/" and like free-format output, starts each line with a space that would be consumed as a carriage-control character for lineprinter output.
 
The "append" to a file is available only if the ACCESS="APPEND" facility is available, and alas, this is not standard Fortran though a common extension. Files opened for output are exclusive use. If a file exists but is in use, the OPEN statement will fail, so one should include the <code>ERR=''label'',IOSTAT=WHAT</code> to attempt to recover from lockouts. Except that IOSTAT error codes for a given problem may well vary from one system to another.
1,220

edits