Selective file copy: Difference between revisions

Content added Content deleted
(Added COBOL)
(→‎{{header|Go}}: Add Fortran.)
Line 270: Line 270:
output, with a DISPLAY statement, the numbers look like text, but the memory
output, with a DISPLAY statement, the numbers look like text, but the memory
representation would be computational bit patterns.
representation would be computational bit patterns.

=={{header|Fortran}}==
In principle the contents of a file can be arbitrarily complex, with the structure really only comprehensible to the program that writes (and maybe reads) it especially if numbers are written in binary format whereby any bit sequence may appear - just consider the content of a "database" file. Thus, a separate program that selectively reads some data from such a file is faced with an arbitrarily difficult problem. However, if what is written is in text format only, various possible conventions might be followed, and in particular, Fortran offers the NAMELIST protocol, as exemplified below:<lang Fortran> PROGRAM TEST !Define some data aggregates, then write and read them.
TYPE PLACE
INTEGER N
CHARACTER*28 PLACENAME
REAL ALTITUDE
COMPLEX LATLONG
END TYPE PLACE
TYPE HOME
CHARACTER*28 PLACENAME
COMPLEX LATLONG
END TYPE HOME
TYPE (PLACE) HERE,THERE !I'll have two.
TYPE (HOME) IS !And one of this.
NAMELIST /STUFF/ HERE,THERE,IS !A collection.
INTEGER F !An I/O unit number.
F = 10 !This will do.

Create an example file to show its format.
OPEN(F,FILE="Test.txt",STATUS="REPLACE",ACTION="WRITE", !First, prepare a recipient file.
1 DELIM="QUOTE") !CHARACTER variables will be enquoted.
HERE = PLACE(1,"Mt. Cook trig.",20.0,(-41.29980555,174.77629)) !Base position for surveying.
THERE = HERE !Copy one data aggregate to another.
THERE.N = 2 !Differentiate.
IS.PLACENAME = "Taipou." !Initialise another,
IS.LATLONG = (0,0) !Piecemeal.
WRITE (F,STUFF) !Write the lot in one go.
CLOSE (F) !Finished with output.
HERE = PLACE(0,"",0,(0,0))!Scrub the variables.
THERE = HERE
IS = HOME("",(0,0))
Can now read from the file.
OPEN(F,FILE="Test.txt",STATUS="OLD",ACTION="READ", !Get it back.
1 DELIM="QUOTE")
READ (F,STUFF) !Read who knows what.
IS.PLACENAME = HERE.PLACENAME !Copy some particular portion.
IS.LATLONG = HERE.LATLONG !Piecemeal, as no common structure was defined.
WRITE (6,*) IS !Reveal the result.
END</lang>
This produces a file in a standard format. All output starts with a space in column one (in case this output were to be sent to a lineprinter, for which that would be the carriage control character), and begins with a special line that gives the name of the NAMELIST prefixed with an ampersand, and ends with a slash. Each line starts with the name of a variable followed by an equals, then comes its value in an appropriate format, just as if it were an assignment statement in Fortran. There is provision for listing the values of arrays also, and sequences of equal values will be shown with a repetition count as in 6*0 for six zero values in a row, alas not using an @ symbol. Structure names alas use % instead of a full stop, but a full stop may be accepted as input.
<pre>
&STUFF
HERE%N = 1,
HERE%PLACENAME = "Mt. Cook trig. ",
HERE%ALTITUDE = 20.00000 ,
HERE%LATLONG = (-41.29980,174.7763),
THERE%N = 2,
THERE%PLACENAME = "Mt. Cook trig. ",
THERE%ALTITUDE = 20.00000 ,
THERE%LATLONG = (-41.29980,174.7763),
IS%PLACENAME = "Taipou. ",
IS%LATLONG = (0.0000000E+00,0.0000000E+00)
/
</pre>
This is suitable for input also. Variables can be named in any order, and, not all need be named. Those named in the NAMELIST but not named in the specific input will not be changed by the READ statement. A READ(F,STUFF) will skip through input blocks until it finds an &STUFF, thus an input file may contain stuff for different NAMELIST collections (thus directly meeting the specification for a "selective file copy"), and if input is being obtained live from the keyboard, one can enter "?" to be advised of the name of the NAMELIST being sought...

This style of input is useful when a large number of different parameters are to be read in, and on a given occasion, many of them may be omitted. It is thus more flexible than having some defined format for all of them, or, reading them all in free-format. Obviously, the names will have mnemonic value.

To revert to the specific task, obviously the input could contain only values for variables of interest, or, if values for all variables are supplied (as in the example), after the READ only those of interest would be copied to other variables to be going on with. In the example, because there is no <code>IS = HERE, BY NAME</code> facility offered by Fortran so that only the elements of HERE that have the same name as elements of IS (in perhaps a different order) will be copied, as in pl/i and others, the copy must be done element-by-element. If however the desired elements had been organised into a substructure (say called LOCATION) and both type PLACE and type HOME had used that substructure, then a single assignment could have been used, as when HERE is copied to THERE.



=={{header|Go}}==
=={{header|Go}}==