gtool5 Fortran 90/95 Library 1.0.0-rc5
日本語
Loading...
Searching...
No Matches
dcstringsprintf.f90 File Reference

Go to the source code of this file.

Functions/Subroutines

subroutine dcstringsprintf (unit, fmt, i, r, d, l, n, c1, c2, c3, ca)
 Formatted output conversion (similar to C sprintf).
subroutine append (unitx, ucur, val, stat)

Function/Subroutine Documentation

◆ append()

subroutine dcstringsprintf::append ( character(*), intent(inout) unitx,
integer, intent(inout) ucur,
character(*), intent(in) val,
integer, intent(out) stat )

Append string to output buffer

Parameters
[in,out]unitxOutput buffer string
[in,out]ucurCurrent position in unitx
[in]valString to append
[out]statStatus (0=success, 1=truncated, 2=overflow)

Definition at line 335 of file dcstringsprintf.f90.

336 character(*), intent(inout):: unitx ! 最終的に返される文字列
337 integer, intent(inout):: ucur ! unitx の文字数
338 character(*), intent(in) :: val ! unitx に付加される文字列
339 integer, intent(out) :: stat ! ステータス
340 integer :: wrsz ! val の文字列
341 continue
342 ! unitx の最大長を越えた場合には stat = 2 を返す。
343 if (ucur >= len(unitx)) then
344 stat = 2
345 ! 正常時の処理
346 else
347 ! unitx の長さを越えた場合も考慮して unitx に val を付加する。
348 wrsz = min(len(val), len(unitx) - ucur)
349 unitx(1+ucur: wrsz+ucur) = val(1: wrsz)
350 ucur = ucur + wrsz
351 stat = 0
352 if (wrsz < len(val)) stat = 1
353 endif

◆ dcstringsprintf()

subroutine dcstringsprintf ( character(*), intent(out) unit,
character(*), intent(in) fmt,
integer, dimension(:), intent(in), optional i,
real(sp), dimension(:), intent(in), optional r,
real(dp), dimension(:), intent(in), optional d,
logical, dimension(:), intent(in), optional l,
integer, dimension(:), intent(in), optional n,
character(*), intent(in), optional c1,
character(*), intent(in), optional c2,
character(*), intent(in), optional c3,
character(*), dimension(:), intent(in), optional ca )

Formatted output conversion (similar to C sprintf).

Author
Yasuhiro MORIKAWA, Eizi TOYODA

Format a string like C sprintf(3). Note that the implementation is quite different from C sprintf(3).

Format specifiers

Format specifiers used in dc_string#CPrintf and dc_string#Printf start with %. Available specifiers are:

Specifier Argument Description
d, D i(:) Display integer (decimal). Use %2d or %04d for digit control
o, O i(:) Display integer (octal)
x, X i(:) Display integer (hexadecimal)
f, F d(:) Display double precision real
r, R r(:) Display single precision real
b, B L(:) Display logical (T/F)
y, Y L(:) Display logical (yes/no)
c, C c1,c2,c3 Display character (variable)
a, A ca Display character (array)
%* n(:) Repeat count for multiple data output

Format and output string to character variable

Return a formatted string according to format string fmt. Use specifiers starting with '' in fmt. Use '%' to output a literal ''. See dcstringsprintf.f90 for specifier details and examples.

Parameters
[out]unitOutput character variable
[in]fmtFormat string with specifiers
[in]iInteger array data for d, o, x
[in]rSingle precision real array data for r
[in]dDouble precision real array data for f
[in]LLogical array data for b, y
[in]nRepeat counts for %* specifier
[in]c1First character string for c
[in]c2Second character string for c
[in]c3Third character string for c
[in]caCharacter array for a

Definition at line 103 of file dcstringsprintf.f90.

104
105 use dc_types, only: sp, dp
106 implicit none
107 character(*), intent(out) :: unit
108 character(*), intent(in) :: fmt
109 integer, intent(in), optional :: i(:), n(:)
110 real(SP), intent(in), optional :: r(:)
111 real(DP), intent(in), optional :: d(:)
112 logical, intent(in), optional :: L(:)
113 character(*), intent(in), optional :: c1, c2, c3
114 character(*), intent(in), optional :: ca(:)
115
116 ! 上記配列引数のカウンタ
117 integer :: ni, nr, nd, nl, nc, na, nn
118 integer :: ucur ! unit に書かれた文字数
119 integer :: endp ! 既に処理された fmt の文字数
120 integer :: cur ! 現在着目中の文字は fmt(cur:cur) である
121 integer :: ptr ! fmt から検索をするときに使用
122 integer :: exp_ptr ! fmt から数値の指数部を検索をするときに使用
123 integer :: minus_ptr ! '-' を検索する時に使用
124 integer :: repeat ! %数字 または %* から決定された繰返し数
125 integer :: m ! 1:repeat の範囲で動くループ変数
126 integer :: stat ! エラー処理
127 character(80) :: cbuf ! read/write 文のバッファ
128 character(80) :: exp_buf ! real/write 文の指数部のバッファ (実数型用)
129 character(80) :: ibuf ! real/write 文のバッファ (整数型用)
130 integer :: len_ibuf ! ibuf の長さ
131 integer :: figs_ibuf ! ibuf の有効な桁数
132 logical :: int_zero_fill ! 先頭を 0 で埋めるかどうかを判定するフラグ (整数型用)
133 integer :: int_figs ! 整数型を出力する際の桁数 (整数型用)
134 continue
135 ni = 0; nr = 0; nd = 0; nl = 0; nc = 0; na = 0; nn = 0
136 unit = ""
137 ucur = 0
138 endp = 0
139 int_figs = 0
140 int_zero_fill = .false.
141 mainloop: do
142 cur = endp + 1
143 if (cur > len(fmt)) exit mainloop
144 !
145 ! リテラルに転写できる文字列 fmt(cur:endp-1) を発見処理
146 !
147 endp = cur - 1 + scan(fmt(cur: ), '%')
148 if (endp > cur) then
149 call append(unit, ucur, fmt(cur:endp-1), stat)
150 if (stat /= 0) exit mainloop
151 else if (endp == cur - 1) then
152 call append(unit, ucur, fmt(cur: ), stat)
153 exit mainloop
154 endif
155 !
156 ! % から書式指定文字までを fmt(cur:endp) とする
157 !
158 cur = endp + 1
159 endp = cur - 1 + scan(fmt(cur: ), 'DdOoXxFfRrBbYySsCcAa%')
160 if (endp < cur) then
161 call append(unit, ucur, fmt(cur-1: ), stat)
162 exit mainloop
163 endif
164 cbuf = fmt(cur:endp-1)
165 !
166 ! %* がある場合、n(:) に渡された数から繰り返し回数を取得
167 !
168 if (cbuf(1:1) == '*') then
169 nn = nn + 1
170 if (nn > size(n)) then
171 repeat = 1
172 else
173 repeat = n(nn)
174 endif
175 ibuf = cbuf(2:)
176 else
177 repeat = 1
178 ibuf = cbuf
179! else if (cbuf == '') then
180! repeat = 1
181! else
182! ptr = verify(cbuf, " 0123456789")
183! if (ptr > 0) cbuf(ptr: ) = " "
184! read(cbuf, "(I80)", iostat=ptr) repeat
185 endif
186 !
187 ! %2d や %04d のように '%' の後ろに数字が指定され、
188 ! かつ d (整数型変数の表示) の場合には先頭に空白
189 ! または 0 を埋める.
190 !
191 if (scan(ibuf(1:1),'1234567890') > 0) then
192 if (ibuf(1:1) == '0') then
193 int_zero_fill = .true.
194 else
195 int_zero_fill = .false.
196 end if
197 read(unit=ibuf, fmt="(i80)") int_figs
198 else
199 int_figs = 0
200 int_zero_fill = .false.
201 endif
202 percentrepeat: do m = 1, repeat
203 if (m > 1) then
204 call append(unit, ucur, ", ", stat)
205 if (stat /= 0) exit mainloop
206 endif
207 select case(fmt(endp:endp))
208 case('d', 'D')
209 if (.not. present(i)) cycle mainloop
210 ni = ni + 1; if (ni > size(i)) cycle mainloop
211 write(ibuf, "(i20)") i(ni)
212 len_ibuf = len(trim(adjustl(ibuf)))
213 figs_ibuf = verify(ibuf, ' ')
214 cbuf = ' '
215 if (int_figs > len_ibuf) then
216 minus_ptr = scan(ibuf, '-')
217 if (int_zero_fill) then
218 if (minus_ptr /= 0) then
219 len_ibuf = len_ibuf - 1
220 figs_ibuf = figs_ibuf + 1
221 cbuf(1:int_figs-len_ibuf) = '-0000000000000000000'
222 else
223 cbuf(1:int_figs-len_ibuf) = '00000000000000000000'
224 end if
225 end if
226 cbuf(int_figs-len_ibuf+1:) = ibuf(figs_ibuf:20)
227 else
228 cbuf = ibuf(figs_ibuf:20)
229 end if
230 call append(unit, ucur, trim(cbuf), stat)
231 if (stat /= 0) exit mainloop
232 case('o', 'O')
233 if (.not. present(i)) cycle mainloop
234 ni = ni + 1; if (ni > size(i)) cycle mainloop
235 write(cbuf, "(o20)") i(ni)
236 call append(unit, ucur, trim(adjustl(cbuf)), stat)
237 if (stat /= 0) exit mainloop
238 case('x', 'X')
239 if (.not. present(i)) cycle mainloop
240 ni = ni + 1; if (ni > size(i)) cycle mainloop
241 write(cbuf, "(z20)") i(ni)
242 call append(unit, ucur, trim(adjustl(cbuf)), stat)
243 if (stat /= 0) exit mainloop
244 case('f', 'F')
245 if (.not. present(d)) cycle mainloop
246 nd = nd + 1; if (nd > size(d)) cycle mainloop
247 write(cbuf, "(f80.40)") d(nd)
248 cbuf = adjustl(cbuf)
249 exp_ptr = verify(cbuf, ' 1234567890-+.', back=.true.)
250 exp_buf = ' '
251 if (exp_ptr > 0) then
252 exp_buf = cbuf(exp_ptr: )
253 cbuf(exp_ptr: ) = " "
254 end if
255 ptr = verify(cbuf, " 0", back=.true.)
256 if (ptr > 0) cbuf(ptr+1: ) = " "
257 cbuf = trim(cbuf) // trim(exp_buf)
258 call append(unit, ucur, trim(adjustl(cbuf)), stat)
259 if (stat /= 0) exit mainloop
260 case('r', 'R')
261 if (.not. present(r)) cycle mainloop
262 nr = nr + 1 ; if (nr > size(r)) cycle mainloop
263 write(cbuf, "(f80.40)") r(nr)
264 cbuf = adjustl(cbuf)
265 exp_ptr = verify(cbuf, ' 1234567890-+.', back=.true.)
266 exp_buf = ' '
267 if (exp_ptr > 0) then
268 exp_buf = cbuf(exp_ptr: )
269 cbuf(exp_ptr: ) = " "
270 end if
271 ptr = verify(cbuf, " 0", back=.true.)
272 if (ptr > 0) cbuf(ptr+1: ) = " "
273 cbuf = trim(cbuf) // trim(exp_buf)
274 call append(unit, ucur, trim(adjustl(cbuf)), stat)
275 if (stat /= 0) exit mainloop
276 case('b', 'B')
277 if (.not. present(l)) cycle mainloop
278 nl = nl + 1; if (nl > size(l)) cycle mainloop
279 write(cbuf, "(L1)") l(nl)
280 call append(unit, ucur, trim(adjustl(cbuf)), stat)
281 if (stat /= 0) exit mainloop
282 case('y', 'Y')
283 if (.not. present(l)) cycle mainloop
284 nl = nl + 1; if (nl > size(l)) cycle mainloop
285 if (l(nl)) then
286 call append(unit, ucur, "yes", stat)
287 if (stat /= 0) exit mainloop
288 else
289 call append(unit, ucur, "no", stat)
290 if (stat /= 0) exit mainloop
291 endif
292 case('c', 'C')
293 nc = nc + 1
294 if (nc == 1) then
295 if (.not. present(c1)) cycle percentrepeat
296 call append(unit, ucur, c1, stat)
297 if (stat /= 0) exit mainloop
298 else if (nc == 2) then
299 if (.not. present(c2)) cycle percentrepeat
300 call append(unit, ucur, c2, stat)
301 if (stat /= 0) exit mainloop
302 else if (nc == 3) then
303 if (.not. present(c3)) cycle percentrepeat
304 call append(unit, ucur, c3, stat)
305 if (stat /= 0) exit mainloop
306 endif
307 case('a', 'A')
308 if (.not. present(ca)) cycle mainloop
309 na = na + 1; if (na > size(ca)) cycle mainloop
310 call append(unit, ucur, trim(adjustl(ca(na))), stat)
311 if (stat /= 0) exit mainloop
312 case('%')
313 call append(unit, ucur, '%', stat)
314 if (stat /= 0) exit mainloop
315 end select
316 enddo percentrepeat
317 enddo mainloop
318 return
319contains
320
321 !> @en
322 !> @brief Append string to output buffer
323 !> @param[inout] unitx Output buffer string
324 !> @param[inout] ucur Current position in unitx
325 !> @param[in] val String to append
326 !> @param[out] stat Status (0=success, 1=truncated, 2=overflow)
327 !> @enden
328 !> @ja
329 !> @brief 出力バッファに文字列を追加
330 !> @param[inout] unitx 出力バッファ文字列
331 !> @param[inout] ucur unitx の現在位置
332 !> @param[in] val 追加する文字列
333 !> @param[out] stat ステータス (0=成功, 1=切り詰め, 2=オーバーフロー)
334 !> @endja
335 subroutine append(unitx, ucur, val, stat)
336 character(*), intent(inout):: unitx ! 最終的に返される文字列
337 integer, intent(inout):: ucur ! unitx の文字数
338 character(*), intent(in) :: val ! unitx に付加される文字列
339 integer, intent(out) :: stat ! ステータス
340 integer :: wrsz ! val の文字列
341 continue
342 ! unitx の最大長を越えた場合には stat = 2 を返す。
343 if (ucur >= len(unitx)) then
344 stat = 2
345 ! 正常時の処理
346 else
347 ! unitx の長さを越えた場合も考慮して unitx に val を付加する。
348 wrsz = min(len(val), len(unitx) - ucur)
349 unitx(1+ucur: wrsz+ucur) = val(1: wrsz)
350 ucur = ucur + wrsz
351 stat = 0
352 if (wrsz < len(val)) stat = 1
353 endif
354 end subroutine append
355
subroutine append(unitx, ucur, val, stat)
Provides kind type parameter values.
Definition dc_types.f90:55
integer, parameter, public dp
Double Precision Real number
Definition dc_types.f90:92
integer, parameter, public sp
Single Precision Real number.
Definition dc_types.f90:82

References append(), dc_types::dp, and dc_types::sp.

Here is the call graph for this function: