dc_string.f90
Go to the documentation of this file.
1 ! -*- mode: f90; coding: utf-8 -*-
2 !-----------------------------------------------------------------------
3 ! Copyright (c) 2000-2017 Gtool Development Group. All rights reserved.
4 !-----------------------------------------------------------------------
9 !
10 ! This file is generated from dc_string.erb by ERB included Ruby 2.3.3.
11 ! Please do not edit this file directly.
23 !
24 module dc_string
25  use dc_types, only: token, string, dp
26  implicit none
27  private
28 
29  public :: stoi
30  public :: stod
31  public :: get_array
32  public :: str_to_logical
33  public :: tochar
34  public :: roundnum
35  public :: joinchar
36  public :: concat
37  public :: stoa
38  public :: split
39  public :: index_ofs
40  public :: replace
41  public :: toupper
42  public :: tolower
43  public :: uchar
44  public :: lchar
45  public :: strieq
46  public :: strhead
47  public :: strinclude
48  ! public :: GTStringQuoteForDcl
49  public :: cprintf
50  public :: printf
51  public :: putline
52 
53  interface stoi
54  module procedure atoi_scalar
55  end interface stoi
56 
57  interface stod
58  module procedure atod_scalar
59  end interface stod
60 
61  interface get_array
62  module procedure str2ip
63  module procedure str2rp
64  module procedure str2dp
65  end interface get_array
66 
67  interface str_to_logical
68  module procedure str2bool
69  end interface str_to_logical
70 
71  !-------------------------------------
72  ! 数値から文字への変換
73  interface tochar
74  module procedure itoa_scalar
75  module procedure itoa_array
76  module procedure rtoa_scalar
77  module procedure rtoa_array
78  module procedure dtoa_scalar
79  module procedure dtoa_array
80  module procedure ltoa_scalar
81  module procedure ltoa_array
82  end interface tochar
83 
84  !-------------------------------------
85  ! 数値表記の文字列の端数除去
86  interface roundnum
87  module procedure roundnum
88  end interface roundnum
89 
90  !-------------------------------------
91  ! 文字型配列の連結
92 
93  !-------------------------------------
94  ! 文字型配列の末尾に文字を連結
95  interface concat
96  module procedure concat_tail
97  end interface concat
98 
99  !-------------------------------------
100  ! 長さの異なる文字群の配列化
101  interface stoa
102  module procedure str_to_array1
103  module procedure str_to_array2
104  module procedure str_to_array3
105  module procedure str_to_array4
106  module procedure str_to_array5
107  module procedure str_to_array6
108  module procedure str_to_array7
109  module procedure str_to_array8
110  module procedure str_to_array9
111  module procedure str_to_array10
112  module procedure str_to_array11
113  module procedure str_to_array12
114  end interface stoa
115 
116  !-------------------------------------
117  ! 文字列の分解
118  interface split
119  module procedure split_cc
120  end interface split
121 
122  !-------------------------------------
123  ! 文字列の解析
124  interface index_ofs
125  module procedure index_ofs
126  end interface index_ofs
127 
128  interface replace
129  module procedure replace
130  end interface replace
131 
132  !-------------------------------------
133  ! 大文字・小文字を無視した処理
134  interface toupper
135  module procedure cupper
136  end interface toupper
137 
138  interface tolower
139  module procedure clower
140  end interface tolower
141 
142  interface uchar
143  module procedure uchar
144  end interface uchar
145 
146  interface lchar
147  module procedure lchar
148  end interface lchar
149 
150  interface strieq
151  module procedure strieq_cc
152  end interface strieq
153 
154  interface strhead
155  module procedure strhead_cc
156  end interface strhead
157 
158  interface strinclude
159  module procedure str_include_ac
160  end interface strinclude
161 
162  !-------------------------------------
163  ! 印字のための文字処理
164  ! interface
165  ! function GTStringQuoteForDcl(string) result(result)
166  ! use dc_types, only: STRLEN => STRING
167  ! character(*), intent(in):: string
168  ! character(STRLEN):: result
169  ! end function GTStringQuoteForDcl
170  ! end interface
171 
172  interface cprintf
173  function dcstringcprintf(fmt, i, r, d, L, n, c1, c2, c3, ca) result(result)
174  use dc_types, only: string, dp
175  character(len = STRING):: result
176  character(*), intent(in):: fmt
177  integer, intent(in), optional:: i(:), n(:)
178  real, intent(in), optional:: r(:)
179  real(DP), intent(in), optional:: d(:)
180  logical, intent(in), optional:: L(:)
181  character(*), intent(in), optional:: c1, c2, c3
182  character(*), intent(in), optional:: ca(:)
183  end function dcstringcprintf
184  end interface cprintf
185 
186  interface printf
187  subroutine dcstringsprintf(unit, fmt, i, r, d, L, n, c1, c2, c3, ca)
188  use dc_types, only: dp
189  character(*), intent(out):: unit
190  character(*), intent(in):: fmt
191  integer, intent(in), optional:: i(:), n(:)
192  real, intent(in), optional:: r(:)
193  real(DP), intent(in), optional:: d(:)
194  logical, intent(in), optional:: L(:)
195  character(*), intent(in), optional:: c1, c2, c3
196  character(*), intent(in), optional:: ca(:)
197  end subroutine dcstringsprintf
198 
199  subroutine dcstringfprintf(unit, fmt, i, r, d, L, n, c1, c2, c3, ca)
200  use dc_types, only: dp
201  integer, intent(in), optional:: unit
202  character(*), intent(in):: fmt
203  integer, intent(in), optional:: i(:), n(:)
204  real, intent(in), optional:: r(:)
205  real(DP), intent(in), optional:: d(:)
206  logical, intent(in), optional:: L(:)
207  character(*), intent(in), optional:: c1, c2, c3
208  character(*), intent(in), optional:: ca(:)
209  end subroutine dcstringfprintf
210 
211  end interface printf
212 
213  !-------------------------------------
214  ! 数値型配列の要約印字
215  interface putline
216  subroutine putlineint1( array, lbounds, ubounds, unit, indent, sd )
217  integer, intent(in):: array(:)
218  integer, intent(in), optional:: lbounds(1)
219  integer, intent(in), optional:: ubounds(1)
220  integer, intent(in), optional:: unit
221  character(*), intent(in), optional:: indent
222  logical, intent(in), optional:: sd
223  end subroutine putlineint1
224  subroutine putlineint2( array, lbounds, ubounds, unit, indent, sd )
225  integer, intent(in):: array(:,:)
226  integer, intent(in), optional:: lbounds(2)
227  integer, intent(in), optional:: ubounds(2)
228  integer, intent(in), optional:: unit
229  character(*), intent(in), optional:: indent
230  logical, intent(in), optional:: sd
231  end subroutine putlineint2
232  subroutine putlineint3( array, lbounds, ubounds, unit, indent, sd )
233  integer, intent(in):: array(:,:,:)
234  integer, intent(in), optional:: lbounds(3)
235  integer, intent(in), optional:: ubounds(3)
236  integer, intent(in), optional:: unit
237  character(*), intent(in), optional:: indent
238  logical, intent(in), optional:: sd
239  end subroutine putlineint3
240  subroutine putlineint4( array, lbounds, ubounds, unit, indent, sd )
241  integer, intent(in):: array(:,:,:,:)
242  integer, intent(in), optional:: lbounds(4)
243  integer, intent(in), optional:: ubounds(4)
244  integer, intent(in), optional:: unit
245  character(*), intent(in), optional:: indent
246  logical, intent(in), optional:: sd
247  end subroutine putlineint4
248  subroutine putlineint5( array, lbounds, ubounds, unit, indent, sd )
249  integer, intent(in):: array(:,:,:,:,:)
250  integer, intent(in), optional:: lbounds(5)
251  integer, intent(in), optional:: ubounds(5)
252  integer, intent(in), optional:: unit
253  character(*), intent(in), optional:: indent
254  logical, intent(in), optional:: sd
255  end subroutine putlineint5
256  subroutine putlineint6( array, lbounds, ubounds, unit, indent, sd )
257  integer, intent(in):: array(:,:,:,:,:,:)
258  integer, intent(in), optional:: lbounds(6)
259  integer, intent(in), optional:: ubounds(6)
260  integer, intent(in), optional:: unit
261  character(*), intent(in), optional:: indent
262  logical, intent(in), optional:: sd
263  end subroutine putlineint6
264  subroutine putlineint7( array, lbounds, ubounds, unit, indent, sd )
265  integer, intent(in):: array(:,:,:,:,:,:,:)
266  integer, intent(in), optional:: lbounds(7)
267  integer, intent(in), optional:: ubounds(7)
268  integer, intent(in), optional:: unit
269  character(*), intent(in), optional:: indent
270  logical, intent(in), optional:: sd
271  end subroutine putlineint7
272  subroutine putlinereal1( array, lbounds, ubounds, unit, indent, sd )
273  use dc_types, only: sp
274  real(SP), intent(in):: array(:)
275  integer, intent(in), optional:: lbounds(1)
276  integer, intent(in), optional:: ubounds(1)
277  integer, intent(in), optional:: unit
278  character(*), intent(in), optional:: indent
279  logical, intent(in), optional:: sd
280  end subroutine putlinereal1
281  subroutine putlinereal2( array, lbounds, ubounds, unit, indent, sd )
282  use dc_types, only: sp
283  real(SP), intent(in):: array(:,:)
284  integer, intent(in), optional:: lbounds(2)
285  integer, intent(in), optional:: ubounds(2)
286  integer, intent(in), optional:: unit
287  character(*), intent(in), optional:: indent
288  logical, intent(in), optional:: sd
289  end subroutine putlinereal2
290  subroutine putlinereal3( array, lbounds, ubounds, unit, indent, sd )
291  use dc_types, only: sp
292  real(SP), intent(in):: array(:,:,:)
293  integer, intent(in), optional:: lbounds(3)
294  integer, intent(in), optional:: ubounds(3)
295  integer, intent(in), optional:: unit
296  character(*), intent(in), optional:: indent
297  logical, intent(in), optional:: sd
298  end subroutine putlinereal3
299  subroutine putlinereal4( array, lbounds, ubounds, unit, indent, sd )
300  use dc_types, only: sp
301  real(SP), intent(in):: array(:,:,:,:)
302  integer, intent(in), optional:: lbounds(4)
303  integer, intent(in), optional:: ubounds(4)
304  integer, intent(in), optional:: unit
305  character(*), intent(in), optional:: indent
306  logical, intent(in), optional:: sd
307  end subroutine putlinereal4
308  subroutine putlinereal5( array, lbounds, ubounds, unit, indent, sd )
309  use dc_types, only: sp
310  real(SP), intent(in):: array(:,:,:,:,:)
311  integer, intent(in), optional:: lbounds(5)
312  integer, intent(in), optional:: ubounds(5)
313  integer, intent(in), optional:: unit
314  character(*), intent(in), optional:: indent
315  logical, intent(in), optional:: sd
316  end subroutine putlinereal5
317  subroutine putlinereal6( array, lbounds, ubounds, unit, indent, sd )
318  use dc_types, only: sp
319  real(SP), intent(in):: array(:,:,:,:,:,:)
320  integer, intent(in), optional:: lbounds(6)
321  integer, intent(in), optional:: ubounds(6)
322  integer, intent(in), optional:: unit
323  character(*), intent(in), optional:: indent
324  logical, intent(in), optional:: sd
325  end subroutine putlinereal6
326  subroutine putlinereal7( array, lbounds, ubounds, unit, indent, sd )
327  use dc_types, only: sp
328  real(SP), intent(in):: array(:,:,:,:,:,:,:)
329  integer, intent(in), optional:: lbounds(7)
330  integer, intent(in), optional:: ubounds(7)
331  integer, intent(in), optional:: unit
332  character(*), intent(in), optional:: indent
333  logical, intent(in), optional:: sd
334  end subroutine putlinereal7
335  subroutine putlinedouble1( array, lbounds, ubounds, unit, indent, sd )
336  use dc_types, only: dp
337  real(DP), intent(in):: array(:)
338  integer, intent(in), optional:: lbounds(1)
339  integer, intent(in), optional:: ubounds(1)
340  integer, intent(in), optional:: unit
341  character(*), intent(in), optional:: indent
342  logical, intent(in), optional:: sd
343  end subroutine putlinedouble1
344  subroutine putlinedouble2( array, lbounds, ubounds, unit, indent, sd )
345  use dc_types, only: dp
346  real(DP), intent(in):: array(:,:)
347  integer, intent(in), optional:: lbounds(2)
348  integer, intent(in), optional:: ubounds(2)
349  integer, intent(in), optional:: unit
350  character(*), intent(in), optional:: indent
351  logical, intent(in), optional:: sd
352  end subroutine putlinedouble2
353  subroutine putlinedouble3( array, lbounds, ubounds, unit, indent, sd )
354  use dc_types, only: dp
355  real(DP), intent(in):: array(:,:,:)
356  integer, intent(in), optional:: lbounds(3)
357  integer, intent(in), optional:: ubounds(3)
358  integer, intent(in), optional:: unit
359  character(*), intent(in), optional:: indent
360  logical, intent(in), optional:: sd
361  end subroutine putlinedouble3
362  subroutine putlinedouble4( array, lbounds, ubounds, unit, indent, sd )
363  use dc_types, only: dp
364  real(DP), intent(in):: array(:,:,:,:)
365  integer, intent(in), optional:: lbounds(4)
366  integer, intent(in), optional:: ubounds(4)
367  integer, intent(in), optional:: unit
368  character(*), intent(in), optional:: indent
369  logical, intent(in), optional:: sd
370  end subroutine putlinedouble4
371  subroutine putlinedouble5( array, lbounds, ubounds, unit, indent, sd )
372  use dc_types, only: dp
373  real(DP), intent(in):: array(:,:,:,:,:)
374  integer, intent(in), optional:: lbounds(5)
375  integer, intent(in), optional:: ubounds(5)
376  integer, intent(in), optional:: unit
377  character(*), intent(in), optional:: indent
378  logical, intent(in), optional:: sd
379  end subroutine putlinedouble5
380  subroutine putlinedouble6( array, lbounds, ubounds, unit, indent, sd )
381  use dc_types, only: dp
382  real(DP), intent(in):: array(:,:,:,:,:,:)
383  integer, intent(in), optional:: lbounds(6)
384  integer, intent(in), optional:: ubounds(6)
385  integer, intent(in), optional:: unit
386  character(*), intent(in), optional:: indent
387  logical, intent(in), optional:: sd
388  end subroutine putlinedouble6
389  subroutine putlinedouble7( array, lbounds, ubounds, unit, indent, sd )
390  use dc_types, only: dp
391  real(DP), intent(in):: array(:,:,:,:,:,:,:)
392  integer, intent(in), optional:: lbounds(7)
393  integer, intent(in), optional:: ubounds(7)
394  integer, intent(in), optional:: unit
395  character(*), intent(in), optional:: indent
396  logical, intent(in), optional:: sd
397  end subroutine putlinedouble7
398  end interface putline
399 
400 contains
401  logical function strhead_cc(whole, head) result(result)
402  !
403  ! 文字列 head と文字列 whole の先頭部分 (head と同じ文字列長)
404  ! とを比較し、同じものならば .true. を、異なる場合には .false.
405  ! を返します。 whole の文字列長が head の文字列長よりも短い場合には
406  ! .false. を返します。
407  !
408  character(len = *), intent(in):: whole
409  character(len = *), intent(in):: head
410 
411  continue
412 
413  result = (len(whole) >= len(head))
414  if (.not. result) return
415  result = (whole(1:len(head)) == head)
416 
417  end function strhead_cc
418 
419  logical function strieq_cc(string_a, string_b) result(result)
420  !
421  ! 大文字・小文字を無視して文字列の比較を行います。
422  ! 文字列 string_a と文字列 string_b を比較し、同じものならば
423  ! .true. を、異なる場合には .false. を返します。
424  !
425  !--
426  ! ※ 注意書き ※
427  !
428  ! コンパイラによっては character(len = len(string_a)):: abuf
429  ! が通らないため, 文字数を dc_types で提供される種別型
430  ! パラメタ STRING で制限
431  !++
432  !
433  character(len = *), intent(in):: string_a
434  character(len = *), intent(in):: string_b
435  character(len = STRING):: abuf
436  character(len = STRING):: bbuf
437  abuf = string_a
438  bbuf = string_b
439  call toupper(abuf)
440  call toupper(bbuf)
441  result = (abuf == bbuf)
442  end function strieq_cc
443 
444  logical function str_include_ac( &
445  & carray, string, ignore_space, ignore_case ) result(result)
446  !
447  ! 文字型配列引数 *carray* が文字型引数 *string* と等しい要素を持つ場合に
448  ! .true. を返します.
449  !
450  ! 文字列の前後の空白は無視されます.
451  ! オプショナル引数 *ignore_space* に .false. を
452  ! 与えた場合には文字列先頭の空白を無視しません.
453  !
454  ! オプショナル引数 *ignore_case* に .true. を与えた場合には
455  ! 大文字, 小文字の違いを無視して比較します.
456  !
457  ! If an character array argument *carray* has the same
458  ! as character argument *string*, ".true." is returned.
459  !
460  ! And beginning and trailing spaces are ignored.
461  ! If ".false." is given to an optional argument *ignore_space*,
462  ! beginning spaces are not ignored.
463  !
464  ! If ".true." is given to an optional argument *ignore_case*,
465  ! this function ignores case.
466  !
467  character(*), intent(in):: carray(:)
468  character(*), intent(in):: string
469  logical, intent(in), optional:: ignore_space
470  logical, intent(in), optional:: ignore_case
471  integer:: array_size, i
472  logical:: ignore_space_work, ignore_case_work
473 
474  continue
475 
476  ignore_space_work = .true.
477  if ( present(ignore_space) ) then
478  if ( .not. ignore_space ) then
479  ignore_space_work = .false.
480  end if
481  end if
482 
483  ignore_case_work = .false.
484  if ( present(ignore_case) ) then
485  if ( ignore_case ) then
486  ignore_case_work = .true.
487  end if
488  end if
489 
490  array_size = size(carray)
491  do i = 1, array_size
492  if ( ignore_space_work ) then
493  if ( ignore_case_work ) then
494  result = &
495  & strieq_cc( trim( adjustl( carray(i) ) ), &
496  & trim( adjustl( string ) ) )
497  else
498  result = &
499  & ( trim( adjustl( carray(i) ) ) == trim( adjustl( string ) ) )
500  end if
501 
502  else
503  if ( ignore_case_work ) then
504  result = &
505  & strieq_cc( trim( carray(i) ), trim( string ) )
506  else
507  result = ( trim(carray(i)) == trim(string) )
508  end if
509  end if
510  if (result) return
511  end do
512  end function str_include_ac
513 
514  logical function str2bool(string) result(result)
515  !
516  ! string で与えられる文字型変数を論理型にして返します。 string
517  ! が空、 または 0、 0.0、 0.0D0、 0.0d0、 .false.、 .FALSE.、 f、
518  ! F、 false、 FALSE の場合には <tt>.false.</tt> が返ります。
519  ! それ以外の場合には <tt>.true.</tt> が返ります。
520  !
521  character(len = *), intent(in):: string
522 
523  continue
524 
525  select case(string)
526  case ("", "0", "0.0", "0.0D0", "0.0d0", ".false.", ".FALSE.", &
527  & "f", "F", "false", "FALSE")
528  result = .false.
529  case default
530  result = .true.
531  end select
532  end function str2bool
533 
534  integer function atoi_scalar(string, default) result(result)
535  !
536  ! string で与えられる文字型変数を、整数型変数にして返します。
537  ! もしも string が数値に変換できない場合、default が返ります。
538  ! default を指定しない場合は 0 が返ります。
539  !
540  character(len = *), intent(in):: string
541  integer, intent(in), optional:: default
542  integer:: ios
543 
544  continue
545 
546  read(unit=string, fmt="(i80)", iostat=ios) result
547  if (ios /= 0) then
548  if (present(default)) then
549  result = default
550  else
551  result = 0
552  endif
553  endif
554  end function atoi_scalar
555 
556  real(DP) function atod_scalar(string_in) result(result)
557  !
558  ! string で与えられる文字型変数を、倍精度実数型変数にして返します。
559  ! もしも string が数値に変換できない場合、0.0 が返ります。
560  !
561  use dc_types, only: string
562  character(len = *), intent(in):: string_in
563  integer:: ios
564  character(len = STRING):: buffer
565  integer:: ipoint, iexp
566  intrinsic scan
567 
568  continue
569 
570  buffer = string_in
571  ! もし整定数をいれてしまった場合は小数点を附加
572  if (index(buffer, '.') == 0) then
573  iexp = scan(buffer, "eEdD")
574  if (iexp /= 0) then
575  buffer(iexp+1: len(buffer)) = buffer(iexp: len(buffer)-1)
576  ipoint = iexp
577  else
578  ipoint = len_trim(buffer) + 1
579  endif
580  buffer(ipoint: ipoint) = '.'
581  endif
582  read(unit=buffer, fmt="(g80.10)", iostat=ios) result
583  if (ios /= 0) result = 0.0
584  end function atod_scalar
585 
586  subroutine str2ip(int_ptr, string_in)
587  !
588  ! string で与えられる文字型変数をカンマ「,」で区切り、
589  ! 整数型配列ポインタ int_ptr(:) にして返します。 int_ptr(:)
590  ! の配列サイズは string の内容に応じて自動的に決まります。
591  !
592  ! ただし、int_ptr(:) は必ず空状態または不定状態で与えてください。
593  ! 既に割り付けられている場合、メモリリークを起こします。
594  !
595  integer, pointer:: int_ptr(:) !(out)
596  character(len = *), intent(in):: string_in
597  integer:: i, j, idx, nvalues
598  continue
599  nvalues = 1
600  i = 1
601  do
602  idx = index(string_in(i: ), ',')
603  if (idx == 0) exit
604  i = i + idx - 1 + 1
605  nvalues = nvalues + 1
606  enddo
607  allocate(int_ptr(nvalues))
608  i = 1
609  j = 1
610  do
611  idx = index(string_in(i: ), ',')
612  if (idx == 0) then
613  int_ptr(j) = stoi(string_in(i: ))
614  exit
615  endif
616  int_ptr(j) = stod(string_in(i: i+idx-2))
617  i = i + idx - 1 + 1
618  j = j + 1
619  enddo
620  end subroutine str2ip
621 
622  subroutine str2rp(real_ptr, string_in)
623  !
624  ! string で与えられる文字型変数をカンマ「,」で区切り、
625  ! 単精度実数型配列ポインタ real_ptr(:) にして返します。
626  ! real_ptr(:) の配列サイズは string の内容に応じて自動的に決まります。
627  !
628  ! ただし、real_ptr(:) は必ず空状態または不定状態で与えてください。
629  ! 既に割り付けられている場合、メモリリークを起こします。
630  !
631  real, pointer:: real_ptr(:) !(out)
632  character(len = *), intent(in):: string_in
633  integer:: i, j, idx, nvalues
634  continue
635  nvalues = 1
636  i = 1
637  do
638  idx = index(string_in(i: ), ',')
639  if (idx == 0) exit
640  i = i + idx - 1 + 1
641  nvalues = nvalues + 1
642  enddo
643  allocate(real_ptr(nvalues))
644  i = 1
645  j = 1
646  do
647  idx = index(string_in(i: ), ',')
648  if (idx == 0) then
649  real_ptr(j) = stod(string_in(i: ))
650  exit
651  endif
652  real_ptr(j) = stod(string_in(i: i+idx-2))
653  i = i + idx - 1 + 1
654  j = j + 1
655  enddo
656  end subroutine str2rp
657 
658  subroutine str2dp(real_ptr, string_in)
659  !
660  ! string で与えられる文字型変数をカンマ「,」で区切り、
661  ! 倍精度実数型配列ポインタ real_ptr(:) にして返します。
662  ! real_ptr(:) の配列サイズは string の内容に応じて自動的に決まります。
663  !
664  ! ただし、real_ptr(:) は必ず空状態または不定状態で与えてください。
665  ! 既に割り付けられている場合、メモリリークを起こします。
666  !
667  real(DP), pointer:: real_ptr(:) !(out)
668  character(len = *), intent(in):: string_in
669  integer:: i, j, idx, nvalues
670  continue
671  nvalues = 1
672  i = 1
673  do
674  idx = index(string_in(i: ), ',')
675  if (idx == 0) exit
676  i = i + idx - 1 + 1
677  nvalues = nvalues + 1
678  enddo
679  allocate(real_ptr(nvalues))
680  i = 1
681  j = 1
682  do
683  idx = index(string_in(i: ), ',')
684  if (idx == 0) then
685  real_ptr(j) = stod(string_in(i: ))
686  exit
687  endif
688  real_ptr(j) = stod(string_in(i: i+idx-2))
689  i = i + idx - 1 + 1
690  j = j + 1
691  enddo
692  end subroutine str2dp
693 
694  !== 数値型、論理型から文字型への変換
695  !
696  ! 総称名称 toChar として呼び出される関数群
697  !
698  character(TOKEN) function itoa_scalar(i) result(result)
699  !
700  ! 整数型変数 i で与えられる数値を文字型変数にして返します。
701  ! 配列が与えられる場合、各要素をカンマと空白「<tt>, </tt>」
702  ! で区切って返します。
703  !
704  integer, intent(in):: i
705  character(len = 32):: buffer
706  continue
707  write(unit=buffer, fmt="(i20)") i
708  result = adjustl(buffer)
709  end function itoa_scalar
710 
711  character(STRING) function itoa_array(ibuf) result(result)
712  !
713  ! 整数型配列変数 ibuf(:) で与えられる数値を文字型変数にして返します。
714  ! 配列が与えられる場合、各要素をカンマと空白「<tt>, </tt>」
715  ! で区切って返します。
716  !
717  integer, intent(in):: ibuf(:)
718  integer:: i
719  continue
720  if (size(ibuf) <= 0) then
721  result = ""
722  return
723  endif
724  result = tochar(ibuf(1))
725  do, i = 2, size(ibuf)
726  result = trim(result) // ", " // trim(tochar(ibuf(i)))
727  enddo
728  end function itoa_array
729 
730  character(TOKEN) function rtoa_scalar(x) result(result)
731  !
732  ! 単精度実数型変数 x で与えられる数値を文字型変数にして返します。
733  ! 配列が与えられる場合、各要素をカンマと空白「<tt>, </tt>」
734  ! で区切って返します。
735  !
736  real, intent(in):: x
737  character(len = 16):: buffer, expbuf
738  integer:: ptr, eptr
739  continue
740  write(unit=buffer, fmt="(g16.8)") x
741  eptr = scan(buffer, "eE", back=.true.)
742  expbuf = ''
743  if (eptr > 1) then
744  expbuf = buffer(eptr: )
745  buffer(eptr: ) = " "
746  end if
747 
748  ptr = verify(buffer, " 0", back=.true.)
749  if (ptr > 0) buffer(ptr+1: ) = " "
750 
751  if (eptr > 1) then
752  buffer = buffer(1:len_trim(buffer)) // expbuf
753  end if
754  result = adjustl(buffer)
755  end function rtoa_scalar
756 
757  character(STRING) function rtoa_array(rbuf) result(result)
758  !
759  ! 単精度実数型配列 rbuf(:)、で与えられる数値を文字型変数にして返します。
760  ! 配列が与えられる場合、各要素をカンマと空白「<tt>, </tt>」
761  ! で区切って返します。
762  !
763  real, intent(in):: rbuf(:)
764  integer:: i
765  continue
766  if (size(rbuf) <= 0) then
767  result = ""
768  return
769  endif
770  result = tochar(rbuf(1))
771  do, i = 2, size(rbuf)
772  result = trim(result) // ", " // trim(tochar(rbuf(i)))
773  enddo
774  end function rtoa_array
775 
776  character(TOKEN) function dtoa_scalar(d) result(result)
777  !
778  ! 倍精度実数型変数 d で与えられる数値を文字型変数にして返します。
779  ! 配列が与えられる場合、各要素をカンマと空白「<tt>, </tt>」
780  ! で区切って返します。
781  !
782  real(DP), intent(in):: d
783  character(len = 32):: buffer, expbuf
784  integer:: ptr, eptr
785  continue
786  write(unit=buffer, fmt="(g32.24)") d
787  eptr = scan(buffer, "eE", back=.true.)
788  expbuf = ''
789  if (eptr > 1) then
790  expbuf = buffer(eptr: )
791  buffer(eptr: ) = " "
792  end if
793 
794  ptr = verify(buffer, " 0", back=.true.)
795  if (ptr > 0) buffer(ptr+1: ) = " "
796 
797  if (eptr > 1) then
798  buffer = buffer(1:len_trim(buffer)) // expbuf
799  end if
800  result = adjustl(buffer)
801  end function dtoa_scalar
802 
803  character(STRING) function dtoa_array(dbuf) result(result)
804  !
805  ! 倍精度実数型配列 dbuf(:) で与えられる数値を文字型変数にして返します。
806  ! 配列が与えられる場合、各要素をカンマと空白「<tt>, </tt>」
807  ! で区切って返します。
808  !
809  real(DP), intent(in):: dbuf(:)
810  integer:: i
811  continue
812  if (size(dbuf) <= 0) then
813  result = ""
814  return
815  endif
816  result = tochar(dbuf(1))
817  do, i = 2, size(dbuf)
818  result = trim(result) // ", " // trim(tochar(dbuf(i)))
819  enddo
820  end function dtoa_array
821 
822  character(TOKEN) function ltoa_scalar(l) result(result)
823  !
824  ! 論理型変数 l で与えられる数値を文字型変数にして返します。
825  ! 配列が与えられる場合、各要素をカンマと空白「<tt>, </tt>」
826  ! で区切って返します。
827  !
828  logical, intent(in):: l
829  continue
830  if (l) then
831  result = ".true."
832  else
833  result = ".false."
834  end if
835  end function ltoa_scalar
836 
837  character(STRING) function ltoa_array(lbuf) result(result)
838  !
839  ! 論理型配列 lbuf(:) で与えられる数値を文字型変数にして返します。
840  ! 配列が与えられる場合、各要素をカンマと空白「<tt>, </tt>」
841  ! で区切って返します。
842  !
843  logical, intent(in):: lbuf(:)
844  integer:: i
845  continue
846  if (size(lbuf) <= 0) then
847  result = ""
848  return
849  endif
850  result = tochar(lbuf(1))
851  do, i = 2, size(lbuf)
852  result = trim(result) // ", " // trim(tochar(lbuf(i)))
853  enddo
854  end function ltoa_array
855 
856  !-------------------------------------------------------------------
857  ! 文字配列の連結
858  !-------------------------------------------------------------------
859 
860  character(STRING) function joinchar(carray, expr) result(result)
861  !
862  ! 文字型配列 carray に与えた複数の文字列をカンマと空白
863  ! 「<tt>, </tt>」 で区切った1つの文字列にして返します。
864  ! expr に文字列を与えると、その文字列を区切り文字として用います。
865  !
866  implicit none
867  character(*) , intent(in) :: carray(:)
868  character(*) , intent(in), optional :: expr
869 
870  character(2) ,parameter :: default = ', '
871  character(STRING) :: delimiter
872  integer :: dellen, i
873  continue
874  if ( present(expr) ) then
875  delimiter = expr
876  dellen = len(expr)
877  else
878  delimiter = default
879  dellen = len(default)
880  endif
881  if (size(carray) <= 0) then
882  result = ""
883  return
884  endif
885  result = trim(carray(1))
886  do, i = 2, size(carray)
887  result = trim(result) // delimiter(1:dellen) // trim(carray(i))
888  enddo
889  end function joinchar
890 
891 
892  subroutine concat_tail(carray, str, result)
893  !
894  ! 文字型配列 *carray* の各成分の末尾に *str* を追加して
895  ! *result* に返します。*carray* の各成分の末尾の空白は無視されます。
896  !
897  ! result(:) の配列サイズは carray のサイズに応じて自動的に決まります。
898  ! ただし、result(:) は必ず空状態または不定状態で与えてください。
899  ! 既に割り付けられている場合、メモリリークを起こします。
900  !
901  implicit none
902  character(*), intent(in) :: carray(:)
903  character(*), intent(in) :: str
904  character(STRING), pointer:: result(:) ! (out)
905  integer :: i, size_carray
906  continue
907  size_carray = size(carray)
908  allocate(result(size_carray))
909 
910  do i = 1, size_carray
911  result(i) = trim(carray(i)) // str
912  end do
913 
914  end subroutine concat_tail
915 
916  function str_to_array1(c1) result(result)
917  !
918  ! 異なる長さの複数の文字型変数を 1 つの文字型配列に変換します。
919  !
920  ! 1 から 1 個までの引数を与えることが可能です。
921  !
922  character(*), intent(in) :: c1
923  character(STRING) :: result(1)
924 
925  continue
926  result(1) = c1
927  end function str_to_array1
928 
929  function str_to_array2(c1,c2) result(result)
930  !
931  ! 異なる長さの複数の文字型変数を 1 つの文字型配列に変換します。
932  !
933  ! 1 から 2 個までの引数を与えることが可能です。
934  !
935  character(*), intent(in) :: c1,c2
936  character(STRING) :: result(2)
937 
938  continue
939  result(1) = c1
940  result(2) = c2
941  end function str_to_array2
942 
943  function str_to_array3(c1,c2,c3) result(result)
944  !
945  ! 異なる長さの複数の文字型変数を 1 つの文字型配列に変換します。
946  !
947  ! 1 から 3 個までの引数を与えることが可能です。
948  !
949  character(*), intent(in) :: c1,c2,c3
950  character(STRING) :: result(3)
951 
952  continue
953  result(1) = c1
954  result(2) = c2
955  result(3) = c3
956  end function str_to_array3
957 
958  function str_to_array4(c1,c2,c3,c4) result(result)
959  !
960  ! 異なる長さの複数の文字型変数を 1 つの文字型配列に変換します。
961  !
962  ! 1 から 4 個までの引数を与えることが可能です。
963  !
964  character(*), intent(in) :: c1,c2,c3,c4
965  character(STRING) :: result(4)
966 
967  continue
968  result(1) = c1
969  result(2) = c2
970  result(3) = c3
971  result(4) = c4
972  end function str_to_array4
973 
974  function str_to_array5(c1,c2,c3,c4,c5) result(result)
975  !
976  ! 異なる長さの複数の文字型変数を 1 つの文字型配列に変換します。
977  !
978  ! 1 から 5 個までの引数を与えることが可能です。
979  !
980  character(*), intent(in) :: c1,c2,c3,c4,c5
981  character(STRING) :: result(5)
982 
983  continue
984  result(1) = c1
985  result(2) = c2
986  result(3) = c3
987  result(4) = c4
988  result(5) = c5
989  end function str_to_array5
990 
991  function str_to_array6(c1,c2,c3,c4,c5,c6) result(result)
992  !
993  ! 異なる長さの複数の文字型変数を 1 つの文字型配列に変換します。
994  !
995  ! 1 から 6 個までの引数を与えることが可能です。
996  !
997  character(*), intent(in) :: c1,c2,c3,c4,c5,c6
998  character(STRING) :: result(6)
999 
1000  continue
1001  result(1) = c1
1002  result(2) = c2
1003  result(3) = c3
1004  result(4) = c4
1005  result(5) = c5
1006  result(6) = c6
1007  end function str_to_array6
1008 
1009  function str_to_array7(c1,c2,c3,c4,c5,c6,c7) result(result)
1010  !
1011  ! 異なる長さの複数の文字型変数を 1 つの文字型配列に変換します。
1012  !
1013  ! 1 から 7 個までの引数を与えることが可能です。
1014  !
1015  character(*), intent(in) :: c1,c2,c3,c4,c5,c6,c7
1016  character(STRING) :: result(7)
1017 
1018  continue
1019  result(1) = c1
1020  result(2) = c2
1021  result(3) = c3
1022  result(4) = c4
1023  result(5) = c5
1024  result(6) = c6
1025  result(7) = c7
1026  end function str_to_array7
1027 
1028  function str_to_array8(c1,c2,c3,c4,c5,c6,c7,c8) result(result)
1029  !
1030  ! 異なる長さの複数の文字型変数を 1 つの文字型配列に変換します。
1031  !
1032  ! 1 から 8 個までの引数を与えることが可能です。
1033  !
1034  character(*), intent(in) :: c1,c2,c3,c4,c5,c6,c7,c8
1035  character(STRING) :: result(8)
1036 
1037  continue
1038  result(1) = c1
1039  result(2) = c2
1040  result(3) = c3
1041  result(4) = c4
1042  result(5) = c5
1043  result(6) = c6
1044  result(7) = c7
1045  result(8) = c8
1046  end function str_to_array8
1047 
1048  function str_to_array9(c1,c2,c3,c4,c5,c6,c7,c8,c9) result(result)
1049  !
1050  ! 異なる長さの複数の文字型変数を 1 つの文字型配列に変換します。
1051  !
1052  ! 1 から 9 個までの引数を与えることが可能です。
1053  !
1054  character(*), intent(in) :: c1,c2,c3,c4,c5,c6,c7,c8,c9
1055  character(STRING) :: result(9)
1056 
1057  continue
1058  result(1) = c1
1059  result(2) = c2
1060  result(3) = c3
1061  result(4) = c4
1062  result(5) = c5
1063  result(6) = c6
1064  result(7) = c7
1065  result(8) = c8
1066  result(9) = c9
1067  end function str_to_array9
1068 
1069  function str_to_array10(c1,c2,c3,c4,c5,c6,c7,c8,c9,c10) result(result)
1070  !
1071  ! 異なる長さの複数の文字型変数を 1 つの文字型配列に変換します。
1072  !
1073  ! 1 から 10 個までの引数を与えることが可能です。
1074  !
1075  character(*), intent(in) :: c1,c2,c3,c4,c5,c6,c7,c8,c9,c10
1076  character(STRING) :: result(10)
1077 
1078  continue
1079  result(1) = c1
1080  result(2) = c2
1081  result(3) = c3
1082  result(4) = c4
1083  result(5) = c5
1084  result(6) = c6
1085  result(7) = c7
1086  result(8) = c8
1087  result(9) = c9
1088  result(10) = c10
1089  end function str_to_array10
1090 
1091  function str_to_array11(c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11) result(result)
1092  !
1093  ! 異なる長さの複数の文字型変数を 1 つの文字型配列に変換します。
1094  !
1095  ! 1 から 11 個までの引数を与えることが可能です。
1096  !
1097  character(*), intent(in) :: c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11
1098  character(STRING) :: result(11)
1099 
1100  continue
1101  result(1) = c1
1102  result(2) = c2
1103  result(3) = c3
1104  result(4) = c4
1105  result(5) = c5
1106  result(6) = c6
1107  result(7) = c7
1108  result(8) = c8
1109  result(9) = c9
1110  result(10) = c10
1111  result(11) = c11
1112  end function str_to_array11
1113 
1114  function str_to_array12(c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12) result(result)
1115  !
1116  ! 異なる長さの複数の文字型変数を 1 つの文字型配列に変換します。
1117  !
1118  ! 1 から 12 個までの引数を与えることが可能です。
1119  !
1120  character(*), intent(in) :: c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12
1121  character(STRING) :: result(12)
1122 
1123  continue
1124  result(1) = c1
1125  result(2) = c2
1126  result(3) = c3
1127  result(4) = c4
1128  result(5) = c5
1129  result(6) = c6
1130  result(7) = c7
1131  result(8) = c8
1132  result(9) = c9
1133  result(10) = c10
1134  result(11) = c11
1135  result(12) = c12
1136  end function str_to_array12
1137 
1138  !-------------------------------------------------------------------
1139  ! 文字列の分解
1140  !-------------------------------------------------------------------
1141 
1142  subroutine split_cc(str, carray, sep, limit)
1143  !
1144  ! *str* で与えられた文字列を 文字列 *sep* で分解し,
1145  ! ポインタ配列 *carray* に返します.
1146  ! *carray* は必ず空状態にして与えてください. 割り付け状態の
1147  ! 場合にはエラーを返します.
1148  !
1149  ! *limit* に正の数を与えた場合, 最大 *limit* 個のフィールドに分割
1150  ! します. 負の数や 0 の場合は省略した場合と同じになります. *str*
1151  ! の末尾の空白は除去されます. *sep* に空文字を代入する場合, 空白
1152  ! 文字で分割されます.
1153  !
1154  use dc_types, only: string
1155  implicit none
1156  character(*), intent(in):: str
1157  character(*), pointer:: carray(:) !(out)
1158  character(*), intent(in):: sep
1159  integer, intent(in), optional:: limit
1160  integer :: num, cur, i, limitnum
1161  character(STRING) :: substr
1162  logical :: end_flag
1163  continue
1164  if (present(limit)) then
1165  if (limit > 0) then
1166  limitnum = limit
1167  else
1168  limitnum = 0
1169  end if
1170  else
1171  limitnum = 0
1172  end if
1173 
1174  if (len(trim(sep)) == 0) then
1175  num = 1
1176  substr = str
1177  ! 重複して無駄だが carray を allocate するため, 何分割するか
1178  ! 調べ, num に格納する.
1179  do
1180  cur = index(trim(substr), ' ')
1181  if (cur == 0) exit
1182  num = num + 1
1183  substr = adjustl(substr(cur + len(sep) :len(substr)))
1184  end do
1185 
1186  if (limitnum /= 0 .and. num > limitnum) num = limitnum
1187  allocate(carray(num))
1188 
1189  substr = str
1190  end_flag = .false.
1191  do i = 1, num
1192  cur = index(trim(substr), ' ')
1193  if (cur == 0 .or. i == num) end_flag = .true.
1194  if (end_flag) then
1195  carray(i) = substr
1196  exit
1197  else
1198  carray(i) = substr(1:cur - 1)
1199  end if
1200  substr = adjustl(substr(cur + len(sep) :len(substr)))
1201  end do
1202 
1203  else
1204  num = 1
1205  substr = str
1206  ! 重複して無駄だが carray を allocate するため, 何分割するか
1207  ! 調べ, num に格納する.
1208  do
1209  cur = index(substr, trim(sep))
1210  if (cur == 0) exit
1211  num = num + 1
1212  substr = substr(cur + len(sep) :len(substr))
1213  end do
1214 
1215  if (limitnum /= 0 .and. num > limitnum) num = limitnum
1216  allocate(carray(num))
1217 
1218  substr = str
1219  end_flag = .false.
1220  do i = 1, num
1221  cur = index(substr, trim(sep))
1222  if (cur == 0 .or. i == num) end_flag = .true.
1223  if (end_flag) then
1224  carray(i) = substr
1225  exit
1226  else
1227  carray(i) = substr(1:cur - 1)
1228  end if
1229  substr = substr(cur + len(sep) :len(substr))
1230  end do
1231  end if
1232 
1233  return
1234 
1235  end subroutine split_cc
1236 
1237 
1238  !-------------------------------------------------------------------
1239  ! 文字列の解析
1240  !-------------------------------------------------------------------
1241 
1242  integer function index_ofs(string, start, substr) result(result)
1243  !
1244  ! 文字列 string の start 文字目以降の文字列の中に substr
1245  ! の文字列が含まれている時、その開始文字位置を返します。
1246  ! 含まれない場合は 0 を返します。
1247  ! 返される開始文字位置は文字列 string の先頭から数えます。
1248  !
1249  character(len = *), intent(in):: string
1250  integer, intent(in):: start
1251  character(len = *), intent(in):: substr
1252  intrinsic index
1253  if (start < 1) then
1254  result = 0
1255  return
1256  endif
1257  result = index(string(start: ), substr)
1258  if (result == 0) return
1259  result = start + result - 1
1260  end function index_ofs
1261 
1262  recursive function replace( &
1263  & string, from, to, recursive, start_pos ) result(result)
1264  !
1265  ! 文字列 *string* に文字列 *from* が含まれる場合, その部分を文字列 *to*
1266  ! に置換して返します. 文字列 *from* が含まれない場合は *string*
1267  ! をそのまま返します. *from* が複数含まれる場合, 先頭の *from*
1268  ! のみが置換されます.
1269  !
1270  ! 全ての *from* を *to* へ変換したい場合には,
1271  ! オプショナル引数 *recursive* に .true. を与えてください.
1272  !
1273  ! デフォルトでは, 文字列の最初から検索を行います.
1274  ! オプショナル引数 *start_pos* を与える場合,
1275  ! *start_pos* 文字目から検索を行います.
1276  !
1277  ! If a string *from* is included in *string*, the string is
1278  ! replace to *to*, and the replaced string is returned.
1279  ! If a string *from* is not included, *string* is returned
1280  ! without change.
1281  ! When multiple *from* are included, only first *from* is replaced.
1282  !
1283  ! In order to replace all *from* to *to*, give ".true." to
1284  ! optional argument *recursive*.
1285  !
1286  ! By default, the string is searched from the top.
1287  ! If optional argument *start_pos* is given,
1288  ! the search is started from *start_pos*.
1289  !
1290  use dc_types, only: strlen => string
1291  implicit none
1292  character(STRLEN):: result
1293  character(*), intent(in):: string, from, to
1294  logical, intent(in), optional:: recursive
1295  integer, intent(in), optional:: start_pos
1296  integer:: sp
1297  integer:: i, isa, isb, iea, ieb
1298  integer:: ir
1299  continue
1300  if ( present(start_pos) ) then
1301  sp = start_pos
1302  else
1303  sp = 1
1304  end if
1305  if ( sp < 1 ) then
1306  sp = 1
1307  end if
1308 
1309  result = string
1310  i = index(result(sp:), from)
1311  if (i == 0) return
1312  i = i + sp - 1
1313  isa = i + len(from)
1314  isb = i + len(to)
1315  if (len(to) < len(from)) then
1316  iea = len(result)
1317  ieb = len(result) + len(to) - len(from)
1318  else
1319  iea = len(result) + len(from) - len(to)
1320  ieb = len(result)
1321  endif
1322  if (len(to) /= len(from)) result(isb:ieb) = result(isa:iea)
1323  result(i:i+len(to)-1) = to
1324 
1325  !-----------------------------------
1326  ! 再帰的処理
1327  ! Recursive process
1328  ir = index(result(i+len(to):), from)
1329  if ( len_trim(from) == 0 ) then
1330  ir = index(trim(result(i+len(to):)), from)
1331  end if
1332  if (ir /= 0) then
1333  if ( present(recursive) ) then
1334  if ( recursive ) then
1335  result = replace( string = result, &
1336  & from = from, to = to, &
1337  & recursive = recursive, &
1338  & start_pos = i+len(to) )
1339  end if
1340  end if
1341  end if
1342 
1343  end function replace
1344 
1345  !-------------------------------------------------------------------
1346  ! 大文字・小文字を無視した処理
1347  !-------------------------------------------------------------------
1348 
1349  subroutine cupper(ch)
1350  !
1351  ! 文字列 ch に英字が含まれる場合、その英字を大文字に変換して ch
1352  ! に返します。 英字でない文字や既に大文字になっている文字は
1353  ! そのまま返します。
1354  !
1355  character(len = *), intent(inout):: ch
1356  integer:: i, lch, idx
1357  continue
1358  lch = len(ch)
1359  do, i = 1, lch
1360  idx = ichar(ch(i:i))
1361  if (97 <= idx .and. idx <= 122) then
1362  ch(i:i)=char(idx - 32)
1363  end if
1364  end do
1365  end subroutine cupper
1366 
1367  subroutine clower(ch)
1368  !
1369  ! 文字列 ch に英字が含まれる場合、その英字を小文字に変換して ch
1370  ! に返します。 英字でない文字や既に小文字になっている文字は
1371  ! そのまま返します。
1372  !
1373  character(len = *), intent(inout):: ch
1374  integer:: i, lch, idx
1375  continue
1376  lch = len(ch)
1377  do, i = 1, lch
1378  idx = ichar(ch(i:i))
1379  if (65 <= idx .and. idx <= 90) then
1380  ch(i:i)=char(idx + 32)
1381  end if
1382  end do
1383  end subroutine clower
1384 
1385  character(STRING) function uchar(ch) result(result)
1386  !
1387  ! 文字列 ch に英字が含まれる場合、その英字を大文字に変換して返します。
1388  ! 英字でない文字や既に大文字になっている文字はそのまま返します。
1389  !
1390  character(len = *), intent(in):: ch
1391  continue
1392  result = ch
1393  call toupper(result)
1394  end function uchar
1395 
1396  character(STRING) function lchar(ch) result(result)
1397  !
1398  ! 文字列 ch に英字が含まれる場合、その英字を小文字に変換して返します。
1399  ! 英字でない文字や既に小文字になっている文字はそのまま返します。
1400  !
1401  character(len = *), intent(in):: ch
1402  continue
1403  result = ch
1404  call tolower(result)
1405  end function lchar
1406 
1407  character(STRING) function roundnum(num) result(result)
1408  !
1409  ! '0.30000001' や '12.999998' などの丸め誤差によって端数が残って
1410  ! しまっている数値表記を '0.3' や '13.' などに整形して返します.
1411  !
1412  character(*), intent(in):: num
1413  character(STRING):: nrv, enrv
1414  integer:: i, moving_up, nrvi, dig, zero_stream
1415  continue
1416  !
1417  ! 実数でないものについてはそのまま返す.
1418  !
1419  if ( scan('.', trim(num) ) == 0 ) then
1420  result = num
1421  return
1422  end if
1423  nrv = num
1424 
1425  !
1426  ! 指数部を避けておく.
1427  !
1428  enrv = ''
1429  i = scan(nrv, "eE", back=.true.)
1430  if ( i > 1 ) then
1431  enrv = nrv(i:)
1432  nrv(i:) = " "
1433  elseif ( i == 1 ) then
1434  result = nrv
1435  return
1436  end if
1437 
1438  !
1439  ! 0.30000001 などの末尾の 1 のような, ゴミの桁の数値を掃除し,
1440  ! 0.3000000 などに整形.
1441  !
1442  if ( index( trim( nrv ), '.') - len_trim( nrv ) < -7 ) then
1443  do while ( index('567890.', nrv(len_trim(nrv):len_trim(nrv)) ) == 0 )
1444  if ( len_trim(nrv) < 2 ) exit
1445  nrv = nrv(1:len_trim(nrv)-1)
1446  end do
1447  end if
1448 
1449  !
1450  ! 0.30000001986 などの末尾の 1 以降のゴミの桁の数値を掃除し,
1451  ! 0.3000000 などに整形.
1452  !
1453  if ( index( trim( nrv ), '.') - len_trim( nrv ) < -7 ) then
1454  dig = index( trim( nrv ), '.') + 1
1455  zero_stream = 0
1456  do while ( dig < len_trim( nrv ) )
1457  if ( nrv(dig:dig) == "0" ) then
1458  zero_stream = zero_stream + 1
1459  else
1460  zero_stream = 0
1461  end if
1462  if ( zero_stream > 7 ) then
1463  nrv(dig:len_trim(nrv)) = '0'
1464  exit
1465  end if
1466  dig = dig + 1
1467  end do
1468  end if
1469 
1470  !
1471  ! 0.3000000 などの末尾の 0 を掃除し,
1472  ! 0.3 などに整形.
1473  !
1474  if ( index( trim( nrv ), '.') /= 0 ) then
1475  do while ( index('123456789.', nrv(len_trim(nrv):len_trim(nrv)) ) == 0 )
1476  if ( len_trim(nrv) < 2 ) exit
1477  nrv = nrv(1:len_trim(nrv)-1)
1478  end do
1479  end if
1480 
1481  !
1482  ! 0.89999998 などの末尾の 8 のような, ゴミの桁の数値を掃除し,
1483  ! 0.8999999 などに整形.
1484  !
1485  moving_up = 0
1486  if ( index( trim( nrv ), '.') - len_trim( nrv ) < -7 ) then
1487  do while ( index('12345690.', nrv(len_trim(nrv):len_trim(nrv)) ) == 0 )
1488  if ( len_trim(nrv) < 2 ) exit
1489  nrv = nrv(1:len_trim(nrv)-1)
1490  end do
1491  moving_up = 1
1492  end if
1493 
1494  !
1495  ! 0.8999999 などの末尾の 9 を掃除し, 繰り上げて
1496  ! 0.9 などに整形.
1497  !
1498  if ( moving_up > 0 ) then
1499  do while ( index('012345678.', nrv(len_trim(nrv):len_trim(nrv)) ) == 0 )
1500  if ( len_trim(nrv) < 2 ) exit
1501  nrv = nrv(1:len_trim(nrv)-1)
1502  end do
1503  end if
1504 
1505  i = len_trim(nrv)
1506  do while ( moving_up > 0 .and. i > 0 )
1507  if ( index('.', nrv(i:i)) /= 0 ) then
1508  i = i - 1
1509  cycle
1510  end if
1511  nrvi = stoi( nrv(i:i) ) + moving_up
1512 
1513  if ( nrvi < 10 ) then
1514  nrv(i:i) = trim( tochar( nrvi ) )
1515  exit
1516  else
1517  nrv(i:i) = '0'
1518  if ( i < 2 ) then
1519  nrv = '10'
1520  exit
1521  else
1522  i = i - 1
1523  cycle
1524  end if
1525  end if
1526  if ( len_trim(nrv) < 2 ) exit
1527  nrv = nrv(1:len_trim(nrv)-1)
1528  end do
1529 
1530  !
1531  ! 0.3000000 などの末尾の 0 を掃除し,
1532  ! 0.3 などに整形.
1533  !
1534  if ( index( trim( nrv ), '.') /= 0 ) then
1535  do while ( index('123456789.', nrv(len_trim(nrv):len_trim(nrv)) ) == 0 )
1536  if ( len_trim(nrv) < 2 ) exit
1537  nrv = nrv(1:len_trim(nrv)-1)
1538  end do
1539  end if
1540 
1541  !
1542  ! 指数部を復帰する
1543  !
1544  if ( len_trim(enrv) > 0 ) then
1545  nrv = trim(nrv) // enrv
1546  end if
1547 
1548  result = nrv
1549  end function roundnum
1550 
1552 end module
character(string) function rtoa_array(rbuf)
Definition: dc_string.f90:758
subroutine clower(ch)
Definition: dc_string.f90:1368
character(string) function, dimension(9) str_to_array9(c1, c2, c3, c4, c5, c6, c7, c8, c9)
Definition: dc_string.f90:1049
character(token) function rtoa_scalar(x)
Definition: dc_string.f90:731
character(string) function, dimension(2) str_to_array2(c1, c2)
Definition: dc_string.f90:930
character(string) function, dimension(4) str_to_array4(c1, c2, c3, c4)
Definition: dc_string.f90:959
subroutine putlinereal3(array, lbounds, ubounds, unit, indent, sd)
character(string) function, dimension(7) str_to_array7(c1, c2, c3, c4, c5, c6, c7)
Definition: dc_string.f90:1010
subroutine putlinedouble2(array, lbounds, ubounds, unit, indent, sd)
real(dp) function atod_scalar(string_in)
Definition: dc_string.f90:557
character(string) function ltoa_array(lbuf)
Definition: dc_string.f90:838
integer, parameter, public token
単語やキーワードを保持する文字型変数の種別型パラメタ
Definition: dc_types.f90:109
logical function str_include_ac(carray, string, ignore_space, ignore_case)
Definition: dc_string.f90:446
subroutine putlinereal1(array, lbounds, ubounds, unit, indent, sd)
subroutine dcstringsprintf(unit, fmt, i, r, d, L, n, c1, c2, c3, ca)
subroutine putlinereal5(array, lbounds, ubounds, unit, indent, sd)
subroutine putlinereal2(array, lbounds, ubounds, unit, indent, sd)
character(string) function itoa_array(ibuf)
Definition: dc_string.f90:712
subroutine putlineint4(array, lbounds, ubounds, unit, indent, sd)
character(token) function ltoa_scalar(l)
Definition: dc_string.f90:823
character(token) function itoa_scalar(i)
Definition: dc_string.f90:699
character(string) function, dimension(10) str_to_array10(c1, c2, c3, c4, c5, c6, c7, c8, c9, c10)
Definition: dc_string.f90:1070
subroutine str2ip(int_ptr, string_in)
Definition: dc_string.f90:587
subroutine putlineint3(array, lbounds, ubounds, unit, indent, sd)
character(string) function, public joinchar(carray, expr)
Definition: dc_string.f90:861
subroutine str2rp(real_ptr, string_in)
Definition: dc_string.f90:623
subroutine split_cc(str, carray, sep, limit)
Definition: dc_string.f90:1143
character(string) function, dimension(1) str_to_array1(c1)
Definition: dc_string.f90:917
subroutine putlineint7(array, lbounds, ubounds, unit, indent, sd)
character(string) function, dimension(8) str_to_array8(c1, c2, c3, c4, c5, c6, c7, c8)
Definition: dc_string.f90:1029
integer, parameter, public dp
倍精度実数型変数
Definition: dc_types.f90:83
subroutine concat_tail(carray, str, result)
Definition: dc_string.f90:893
character(string) function, dimension(11) str_to_array11(c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11)
Definition: dc_string.f90:1092
character(string) function, dimension(5) str_to_array5(c1, c2, c3, c4, c5)
Definition: dc_string.f90:975
subroutine putlinereal4(array, lbounds, ubounds, unit, indent, sd)
character(string) function, dimension(12) str_to_array12(c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12)
Definition: dc_string.f90:1115
subroutine cupper(ch)
Definition: dc_string.f90:1350
文字型変数の操作.
Definition: dc_string.f90:24
character(string) function, dimension(6) str_to_array6(c1, c2, c3, c4, c5, c6)
Definition: dc_string.f90:992
subroutine dcstringfprintf(unit, fmt, i, r, d, L, n, c1, c2, c3, ca)
種別型パラメタを提供します。
Definition: dc_types.f90:49
subroutine putlinedouble1(array, lbounds, ubounds, unit, indent, sd)
subroutine putlinedouble3(array, lbounds, ubounds, unit, indent, sd)
logical function strieq_cc(string_a, string_b)
Definition: dc_string.f90:420
subroutine putlinedouble5(array, lbounds, ubounds, unit, indent, sd)
integer, parameter, public sp
単精度実数型変数
Definition: dc_types.f90:73
subroutine putlinedouble4(array, lbounds, ubounds, unit, indent, sd)
subroutine putlineint6(array, lbounds, ubounds, unit, indent, sd)
subroutine putlinereal6(array, lbounds, ubounds, unit, indent, sd)
character(string) function, dimension(3) str_to_array3(c1, c2, c3)
Definition: dc_string.f90:944
logical function strhead_cc(whole, head)
Definition: dc_string.f90:402
logical function str2bool(string)
Definition: dc_string.f90:515
subroutine putlineint1(array, lbounds, ubounds, unit, indent, sd)
subroutine putlineint5(array, lbounds, ubounds, unit, indent, sd)
character(string) function dtoa_array(dbuf)
Definition: dc_string.f90:804
subroutine putlineint2(array, lbounds, ubounds, unit, indent, sd)
subroutine putlinereal7(array, lbounds, ubounds, unit, indent, sd)
character(token) function dtoa_scalar(d)
Definition: dc_string.f90:777
character(len=string) function dcstringcprintf(fmt, i, r, d, L, n, c1, c2, c3, ca)
subroutine putlinedouble7(array, lbounds, ubounds, unit, indent, sd)
integer function atoi_scalar(string, default)
Definition: dc_string.f90:535
subroutine putlinedouble6(array, lbounds, ubounds, unit, indent, sd)
subroutine str2dp(real_ptr, string_in)
Definition: dc_string.f90:659
integer, parameter, public string
文字列を保持する 文字型変数の種別型パラメタ
Definition: dc_types.f90:118