|
| 1 | +module stdlib_experimental_io |
| 2 | +use iso_fortran_env, only: sp=>real32, dp=>real64 |
| 3 | +implicit none |
| 4 | +private |
| 5 | +public :: loadtxt, savetxt |
| 6 | + |
| 7 | +interface loadtxt |
| 8 | + module procedure sloadtxt |
| 9 | + module procedure dloadtxt |
| 10 | +end interface |
| 11 | + |
| 12 | +interface savetxt |
| 13 | + module procedure ssavetxt |
| 14 | + module procedure dsavetxt |
| 15 | +end interface |
| 16 | + |
| 17 | +contains |
| 18 | + |
| 19 | +subroutine sloadtxt(filename, d) |
| 20 | +character(len=*), intent(in) :: filename |
| 21 | +real(sp), allocatable, intent(out) :: d(:,:) |
| 22 | +real(dp), allocatable :: tmp(:,:) |
| 23 | +call dloadtxt(filename, tmp) |
| 24 | +allocate(d(size(tmp,1),size(tmp,2))) |
| 25 | +d = real(tmp,sp) |
| 26 | +end subroutine |
| 27 | + |
| 28 | +subroutine dloadtxt(filename, d) |
| 29 | +! Loads a 2D array from a text file. |
| 30 | +! |
| 31 | +! Arguments |
| 32 | +! --------- |
| 33 | +! |
| 34 | +! Filename to load the array from |
| 35 | +character(len=*), intent(in) :: filename |
| 36 | +! The array 'd' will be automatically allocated with the correct dimensions |
| 37 | +real(dp), allocatable, intent(out) :: d(:,:) |
| 38 | +! |
| 39 | +! Example |
| 40 | +! ------- |
| 41 | +! |
| 42 | +! real(dp), allocatable :: data(:, :) |
| 43 | +! call loadtxt("log.txt", data) ! 'data' will be automatically allocated |
| 44 | +! |
| 45 | +! Where 'log.txt' contains for example:: |
| 46 | +! |
| 47 | +! 1 2 3 |
| 48 | +! 2 4 6 |
| 49 | +! 8 9 10 |
| 50 | +! 11 12 13 |
| 51 | +! ... |
| 52 | +! |
| 53 | +character :: c |
| 54 | +integer :: s, ncol, nrow, ios, i |
| 55 | +logical :: lastwhite |
| 56 | +real(dp) :: r |
| 57 | + |
| 58 | +open(newunit=s, file=filename, status="old") |
| 59 | + |
| 60 | +! determine number of columns |
| 61 | +ncol = 0 |
| 62 | +lastwhite = .true. |
| 63 | +do |
| 64 | + read(s, '(a)', advance='no', iostat=ios) c |
| 65 | + if (ios /= 0) exit |
| 66 | + if (lastwhite .and. .not. whitechar(c)) ncol = ncol + 1 |
| 67 | + lastwhite = whitechar(c) |
| 68 | +end do |
| 69 | + |
| 70 | +rewind(s) |
| 71 | + |
| 72 | +! determine number or rows |
| 73 | +nrow = 0 |
| 74 | +do |
| 75 | + read(s, *, iostat=ios) r |
| 76 | + if (ios /= 0) exit |
| 77 | + nrow = nrow + 1 |
| 78 | +end do |
| 79 | + |
| 80 | +rewind(s) |
| 81 | + |
| 82 | +allocate(d(nrow, ncol)) |
| 83 | +do i = 1, nrow |
| 84 | + read(s, *) d(i, :) |
| 85 | +end do |
| 86 | +close(s) |
| 87 | +end subroutine |
| 88 | + |
| 89 | +subroutine ssavetxt(filename, d) |
| 90 | +character(len=*), intent(in) :: filename |
| 91 | +real(sp), intent(in) :: d(:,:) |
| 92 | +call dsavetxt(filename, real(d,dp)) |
| 93 | +end subroutine |
| 94 | + |
| 95 | +subroutine dsavetxt(filename, d) |
| 96 | +! Saves a 2D array into a textfile. |
| 97 | +! |
| 98 | +! Arguments |
| 99 | +! --------- |
| 100 | +! |
| 101 | +character(len=*), intent(in) :: filename ! File to save the array to |
| 102 | +real(dp), intent(in) :: d(:,:) ! The 2D array to save |
| 103 | +! |
| 104 | +! Example |
| 105 | +! ------- |
| 106 | +! |
| 107 | +! real(dp) :: data(3, 2) |
| 108 | +! call savetxt("log.txt", data) |
| 109 | + |
| 110 | +integer :: s, i |
| 111 | +open(newunit=s, file=filename, status="replace") |
| 112 | +do i = 1, size(d, 1) |
| 113 | + write(s, *) d(i, :) |
| 114 | +end do |
| 115 | +close(s) |
| 116 | +end subroutine |
| 117 | + |
| 118 | + |
| 119 | +logical function whitechar(char) ! white character |
| 120 | +! returns .true. if char is space (32) or tab (9), .false. otherwise |
| 121 | +character, intent(in) :: char |
| 122 | +if (iachar(char) == 32 .or. iachar(char) == 9) then |
| 123 | + whitechar = .true. |
| 124 | +else |
| 125 | + whitechar = .false. |
| 126 | +end if |
| 127 | +end function |
| 128 | + |
| 129 | +end module |
0 commit comments