Skip to content

Commit d30e087

Browse files
fioljJuan Fioljvdp1jalvesz
authored
Savetxt options (#1177)
* Added optional arguments: header, footer, comment to savetxt * Fixed missing dummy args in savetxt * updated savetxt spec * implemented arbitrary-length delimiter * Added optional fmt argument to savetxt (after header and delimiter) * Overloaded savetxt version with unit instead of filename * Fixed error in default format * Fixed introduced error in savetxt format * Fixed typo and added short example with headings * fixed typo in code (comment -> comments) * Fixed mistake (allocatable length 1 char) * Added "correctly" header and footer * Fixed formatting for easier reveiew * Corrected arguments, made comments arbitrary length, check open unit * Corrected specs. filename and unit in different calls * Added option `newline` as in Numpy savetxt * Corrected introduced errors in savetxt * correct IF -> if in src/stdlib_io.fypp Co-authored-by: Jeremie Vandenplas <jeremie.vandenplas@gmail.com> * Fixed error in footer of savetxt and added tests * test_headfoot is failing now * Added individual tests for optional arguments to savetxt * Corrected explanation on filename|unit in savetxt * Fixed test for savetxt(unit, ...) * Update doc/specs/stdlib_io.md Co-authored-by: Jeremie Vandenplas <jeremie.vandenplas@gmail.com> * Accept suggestion. Update src/io/stdlib_io.fypp Co-authored-by: Jeremie Vandenplas <jeremie.vandenplas@gmail.com> * Updated following suggestions by review Added: - comments with intent of variable `fout` - stop the program if unit file is not open - clean-up comments * Added explanation of savetxt behavior for first argument and example Added clarification of use with filename and unit. Also added an example * fixed typo * Added option `append` to form savetxt(filename, ...) * Added checks for open file and writable unit * Remove option `append` from savetxt * Clean-up and added expected output * Update doc/specs/stdlib_io.md Co-authored-by: José Alves <102541118+jalvesz@users.noreply.github.com> * Update src/io/stdlib_io.fypp Co-authored-by: José Alves <102541118+jalvesz@users.noreply.github.com> * Update doc/specs/stdlib_io.md Co-authored-by: José Alves <102541118+jalvesz@users.noreply.github.com> * Changes in some whitespace and filename in example --------- Co-authored-by: Juan Fiol <fiol@cab.cnea.gov.ar> Co-authored-by: Jeremie Vandenplas <jeremie.vandenplas@gmail.com> Co-authored-by: José Alves <102541118+jalvesz@users.noreply.github.com>
1 parent 72698fd commit d30e087

6 files changed

Lines changed: 362 additions & 44 deletions

File tree

doc/specs/stdlib_io.md

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -104,21 +104,37 @@ Experimental
104104
### Description
105105
Saves a rank-2 `array` into a text file.
106106

107+
If the text file already exists:
108+
- When called with a character expression `filename` as the first argument it will overwrite the file.
109+
- When called with an integer number `unit` to an open file as the first argument, it will save data to the file with no further manipulation.
110+
107111
### Syntax
108112

109-
`call ` [[stdlib_io(module):savetxt(interface)]] `(filename, array [, delimiter])`
113+
`call ` [[stdlib_io(module):savetxt(interface)]] `(filename, array [, delimiter] [, fmt] [, header] [, footer] [, comments])`
114+
115+
`call ` [[stdlib_io(module):savetxt(interface)]] `(unit, array [, delimiter] [, fmt] [, header] [, footer] [, comments])`
110116

111117
### Arguments
112118

113-
`filename`: Shall be a character expression containing the name of the file that will contain the 2D `array`.
119+
`filename` or `unit`: Shall be either a character expression containing the name of the file or an integer containing the unit of an already open file, that will contain the 2D `array`.
114120

115121
`array`: Shall be a rank-2 array of type `real`, `complex` or `integer`.
116122

117-
`delimiter` (optional): Shall be a character expression of length 1 that contains the delimiter used to separate the columns. The default is `' '`.
123+
`delimiter` (optional): Shall be a character expression of any length that contains the delimiter used to separate the columns. The default is a single space `' '`.
124+
125+
`fmt` (optional): Fortran format specifier for the text save. Defaults to the write format for the data type as defined in the [formatting constants]{formatting-constants}.
126+
127+
`header` (optional): Shall be a character expression that will be written at the beginning of the file.
128+
129+
`footer` (optional): Shall be a character expression that will be written at the end of the file.
130+
131+
`comments` (optional): Shall be a character expression of any length that will be prepended to the ``header`` and ``footer`` strings to mark them as comments. Default: `#`.
132+
118133

119134
### Output
120135

121-
Provides a text file called `filename` that contains the rank-2 `array`.
136+
Provides a text file called `filename` that contains the rank-2 `array` with optional `header` and `footer` lines.
137+
122138

123139
### Example
124140

@@ -247,7 +263,7 @@ Read a whole line from a formatted unit into a string variable
247263
{!example/io/example_get_line.f90!}
248264
```
249265

250-
## Formatting constants
266+
## Formatting constants {formatting-constants}
251267

252268
### Status
253269

@@ -277,7 +293,7 @@ The function provides an optional error-handling mechanism via the `state_type`
277293

278294
### Syntax
279295

280-
`call [[stdlib_io(module):get_file(subroutine)]] (filename, file [, err] [, delete=.false.])`
296+
`call ` [[stdlib_io(module):get_file(subroutine)]] ` (filename, file [, err] [, delete=.false.])`
281297

282298
### Class
283299
Function

example/io/example.csv

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
1.00000000E+00, 1.00000000E+00
2-
1.00000000E+00, 1.00000000E+00
3-
1.00000000E+00, 1.00000000E+00
1+
1.00000000E+00, 4.00000000E+00
2+
2.00000000E+00, 5.00000000E+00
3+
3.00000000E+00, 6.00000000E+00

example/io/example.dat

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
1.00000000E+00 1.00000000E+00
2-
1.00000000E+00 1.00000000E+00
3-
1.00000000E+00 1.00000000E+00
1+
1.00000000E+00 4.00000000E+00
2+
2.00000000E+00 5.00000000E+00
3+
3.00000000E+00 6.00000000E+00

example/io/example_savetxt.f90

Lines changed: 68 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,70 @@
11
program example_savetxt
2-
use stdlib_io, only: savetxt
3-
implicit none
4-
real :: x(3, 2) = 1
5-
call savetxt('example.dat', x)
6-
call savetxt('example.csv', x, delimiter=',')
2+
use stdlib_io, only: savetxt
3+
use, intrinsic :: iso_fortran_env, only: output_unit
4+
5+
implicit none
6+
real :: x(3, 2)
7+
integer :: unit
8+
x = reshape([1, 2, 3, 4, 5, 6], [3, 2])
9+
10+
! Output to file, default options
11+
call savetxt('example.dat', x)
12+
! Result in example.dat:
13+
! 1.00000000E+00 4.00000000E+00
14+
! 2.00000000E+00 5.00000000E+00
15+
! 3.00000000E+00 6.00000000E+00
16+
!
17+
! Output to file, with custom delimiter
18+
call savetxt('example.csv', x, delimiter=',')
19+
! Result in example.csv:
20+
! 1.00000000E+00, 4.00000000E+00
21+
! 2.00000000E+00, 5.00000000E+00
22+
! 3.00000000E+00, 6.00000000E+00
23+
!
24+
! Output to file, with header and footer and custom comment string
25+
call savetxt('example2.dat', x, header='x (x-units) y (y-units)', comments='!#', footer='This is all data')
26+
! Result in example2.dat:
27+
!!# x (x-units) y (y-units)
28+
! 1.00000000E+00 4.00000000E+00
29+
! 2.00000000E+00 5.00000000E+00
30+
! 3.00000000E+00 6.00000000E+00
31+
!!# This is all data
32+
!
33+
! Output to file. Custom format
34+
call savetxt('example3.dat', x, fmt='f4.2')
35+
! Result in example3.dat:
36+
! 1.00 4.00
37+
! 2.00 5.00
38+
! 3.00 6.00
39+
!
40+
! Output to standard output. Diferent formats for the columns
41+
call savetxt(output_unit, x, header='x y', fmt='(f4.2,1x,f3.1)')
42+
! Output:
43+
! # x y
44+
! 1.00 4.0
45+
! 2.00 5.0
46+
! 3.00 6.0
47+
!
48+
! Save data and then overwrite it:
49+
call savetxt('example4.dat', x)
50+
call savetxt('example4.dat', 2 * x)
51+
! Result in example4.dat:
52+
! 2.00000000E+00 8.00000000E+00
53+
! 4.00000000E+00 1.00000000E+01
54+
! 6.00000000E+00 1.20000000E+01
55+
56+
! Save data and then append some more:
57+
open (newunit=unit, file='example5.dat')
58+
call savetxt(unit, x, header='x (x-units) y (y-units)')
59+
call savetxt(unit, 2 * x)
60+
close (unit)
61+
! Result in example5.dat:
62+
! # x (x-units) y (y-units)
63+
! 1.00000000E+00 4.00000000E+00
64+
! 2.00000000E+00 5.00000000E+00
65+
! 3.00000000E+00 6.00000000E+00
66+
! 2.00000000E+00 8.00000000E+00
67+
! 4.00000000E+00 1.00000000E+01
68+
! 6.00000000E+00 1.20000000E+01
69+
770
end program example_savetxt

0 commit comments

Comments
 (0)