@@ -229,6 +229,7 @@ subroutine read_csv_file(me,filename,header_row,skip_rows,status_ok)
229
229
! ! class have been allocated
230
230
integer :: iheader ! ! row number of header row
231
231
! ! (0 if no header specified)
232
+ character (len= 1 ) :: tmp ! ! for skipping a row
232
233
233
234
call me% destroy()
234
235
arrays_allocated = .false.
@@ -267,7 +268,17 @@ subroutine read_csv_file(me,filename,header_row,skip_rows,status_ok)
267
268
268
269
! skip row if necessary
269
270
if (allocated (rows_to_skip)) then
270
- if (any (i== rows_to_skip)) cycle
271
+ if (any (i== rows_to_skip)) then
272
+ read (iunit,fmt= ' (A1)' ,iostat= istat) tmp
273
+ if (istat/= 0 ) then
274
+ if (me% verbose) write (error_unit,' (A)' ) &
275
+ ' Error skipping row in file: ' // trim (filename)
276
+ close (unit= iunit,iostat= istat)
277
+ status_ok = .false.
278
+ return
279
+ end if
280
+ cycle
281
+ end if
271
282
end if
272
283
273
284
call me% read_line_from_file(iunit,line,status_ok)
@@ -884,10 +895,11 @@ subroutine get_column(me,icol,r,status_ok)
884
895
integer ,intent (in ) :: icol ! ! column number
885
896
class(* ),dimension (:),intent (out ) :: r ! ! assumed to have been allocated to
886
897
! ! the correct size by the caller.
887
- ! ! (n_rows)
898
+ ! ! (` n_rows` )
888
899
logical ,intent (out ) :: status_ok ! ! status flag
889
900
890
901
integer :: i ! ! counter
902
+ character (len= :),allocatable :: tmp ! ! for gfortran workaround
891
903
892
904
! we know the data is allocated, since that
893
905
! was checked by the calling routines.
@@ -896,8 +908,19 @@ subroutine get_column(me,icol,r,status_ok)
896
908
897
909
do i= 1 ,me% n_rows ! row loop
898
910
911
+ #if defined __GFORTRAN__
912
+ ! the following is a workaround for gfortran bugs:
913
+ select type (r)
914
+ type is (character (len=* ))
915
+ tmp = repeat (' ' ,len (r)) ! size the string
916
+ call me% csv_get_value(i,icol,tmp,status_ok)
917
+ r(i) = tmp
918
+ class default
919
+ call me% csv_get_value(i,icol,r(i),status_ok)
920
+ end select
921
+ #else
899
922
call me% csv_get_value(i,icol,r(i),status_ok)
900
-
923
+ # endif
901
924
if (.not. status_ok) then
902
925
select type (r)
903
926
! note: character conversion can never fail, so not
@@ -1174,11 +1197,10 @@ end subroutine read_line_from_file
1174
1197
!
1175
1198
! ### Example
1176
1199
! ````Fortran
1177
- ! type(csv_file) :: f
1178
1200
! character(len=:),allocatable :: s
1179
1201
! type(csv_string),dimension(:),allocatable :: vals
1180
1202
! s = '1,2,3,4,5'
1181
- ! vals = f% split(s,',')
1203
+ ! call split(s,',',vals )
1182
1204
! ````
1183
1205
!
1184
1206
! @warning Doesn't seem to work for `len(token)>1`
@@ -1201,23 +1223,38 @@ pure subroutine split(str,token,chunk_size,vals)
1201
1223
integer :: i1 ! ! index
1202
1224
integer :: i2 ! ! index
1203
1225
integer :: j ! ! counters
1204
- character (len = :),allocatable :: temp
1205
- integer , dimension (:), allocatable :: itokens
1226
+ integer , dimension ( :),allocatable :: itokens ! ! start indices of the
1227
+ ! ! token locations in `str`
1206
1228
1207
- temp = str ! make a copy of the string
1208
1229
len_token = len (token) ! length of the token
1209
- n_tokens = 0 ! initialize the number of token counter
1210
- j = 0 ! length of string removed
1230
+ n_tokens = 0 ! initialize the token counter
1231
+ j = 0 ! index to start looking for the next token
1232
+
1233
+ ! first, count the number of times the token
1234
+ ! appears in the string, and get the token indices.
1235
+ !
1236
+ ! Examples:
1237
+ ! ', ' --> 1
1238
+ ! '1234,67,90' --> 5,8
1239
+ ! '123, ' --> 4
1240
+
1241
+ ! length of the string
1242
+ if (token == ' ' ) then
1243
+ ! in this case, we can't ignore trailing space
1244
+ len_str = len (str)
1245
+ else
1246
+ ! safe to ignore trailing space when looking for tokens
1247
+ len_str = len_trim (str)
1248
+ end if
1211
1249
1212
- ! first, count the number of times the token appears in the string
1250
+ j = 1
1251
+ n_tokens = 0
1213
1252
do
1214
- len_str = len (temp) ! length of the string
1215
- i = index (temp,token) ! location of the next token
1216
- if (i<= 0 ) exit ! no more tokens found
1217
- call expand_vector(itokens,n_tokens,chunk_size,i+ j) ! save the token location
1218
- if (i+ len_token> len_str) exit ! if the last bit of the string is a token
1219
- j = j + i
1220
- temp = trim (temp(i+ len_token:len_str)) ! remove previously scanned part of string
1253
+ if (j> len_str) exit ! end of string, finished
1254
+ i = index (str(j:),token) ! index of next token in remaining string
1255
+ if (i<= 0 ) exit ! no more tokens found
1256
+ call expand_vector(itokens,n_tokens,chunk_size,i+ j-1 ) ! save the token location
1257
+ j = j + i + (len_token - 1 )
1221
1258
end do
1222
1259
call expand_vector(itokens,n_tokens,chunk_size,finished= .true. ) ! resize the vector
1223
1260
0 commit comments