Appearance
5. Files and paths
The table is in a file, data/cars.csv, whose name report now takes from the command line:
year, make, model, price, notes
1997, Ford, E350, 3000.00, ac abs moon
1999, Chevy, Venture, 4900.50, extended edition
2001, Fiat, Punto, 2500, a small city car with a low fuel consumption and a surprisingly large bootThe pieces of a path
f90
print '(A)', 'directory: '//input%basedir()
print '(A)', 'file: '//input%basename()
print '(A)', 'extension: '//input%extension()
output = input%basename(strip_last_extension=.true.)//'.md'
print '(A,L2)', 'a CSV file:', input%match('*.csv') ! a wildcard patternbasedir, basename and extension take a path apart. basename can also drop the last extension: this is how report names its output after its input. match compares the whole string with a wildcard pattern, * any sequence of characters, ? one character, [...] a character of a set; glob uses the same patterns to list the files that match.
Reading
f90
call read_file(file=input%chars(), lines=rows) ! one string for each line
print '(I0,A)', size(rows), ' rows read from '//inputread_file reads the whole file and allocates one string for each line, each of its own length. It takes the name of the file as a character: input%chars().
Writing
f90
allocate(table(size(rows) + 1))
do r = 1, size(rows)
call rows(r)%split(tokens=cells, sep=',')
cells = cells%strip()
table(merge(1, r + 1, r == 1)) = '| '//glue%join(array=cells(1:4), sep=' | ')//' |'
enddo
table(2) = '|---|---|---|---|'
call write_file(file=output%chars(), lines=table)
print '(A)', 'table written to '//outputEach row is split, cleaned and joined again as a row of a Markdown table; write_file writes an array of strings, one for each line.
Running it
$ report data/cars.csv
directory: data
file: cars.csv
extension: .csv
a CSV file: T
4 rows read from data/cars.csv
table written to cars.md$ cat cars.md
| year | make | model | price |
|---|---|---|---|
| 1997 | Ford | E350 | 3000.00 |
| 1999 | Chevy | Venture | 4900.50 |
| 2001 | Fiat | Punto | 2500 |The whole program:
f90
program report
!< Tutorial, chapter 5: files and paths.
use stringifor
implicit none
type(string) :: input, output, glue
type(string), allocatable :: rows(:), cells(:), table(:)
character(256) :: argument
integer :: r
call get_command_argument(1, argument)
input = trim(argument)
print '(A)', 'directory: '//input%basedir()
print '(A)', 'file: '//input%basename()
print '(A)', 'extension: '//input%extension()
output = input%basename(strip_last_extension=.true.)//'.md'
print '(A,L2)', 'a CSV file:', input%match('*.csv') ! a wildcard pattern
call read_file(file=input%chars(), lines=rows) ! one string for each line
print '(I0,A)', size(rows), ' rows read from '//input
allocate(table(size(rows) + 1))
do r = 1, size(rows)
call rows(r)%split(tokens=cells, sep=',')
cells = cells%strip()
table(merge(1, r + 1, r == 1)) = '| '//glue%join(array=cells(1:4), sep=' | ')//' |'
enddo
table(2) = '|---|---|---|---|'
call write_file(file=output%chars(), lines=table)
print '(A)', 'table written to '//output
endprogram reportWhat you learned
read_file and write_file for whole files; basedir, basename, extension for the paths; match for wildcard patterns. Reference: Files and Paths.
Next: 6. A polished report.