fortran-lang/stdlib

Function to format variable as string

Closed this issue · 5 comments

We can already format integer and logical variables to strings, but we don't have routines to write floating point values yet. Maybe we can implement a simple solution by wrapping the internal IO in a function as a separate module. The size of the buffer might be problematic since it can overflow in case a format specifier like '(10000x, g0)' is passed.

The actual implementation is pretty straight-forward:

! SPDX-Identifier: MIT
#:include "common.fypp"
#:set KINDS_TYPES = REAL_KINDS_TYPES + INT_KINDS_TYPES + LOG_KINDS_TYPES

!> Routines for dealing with format specifiers
module stdlib_format
    use stdlib_kinds, only : sp, dp, qp, int8, int16, int32, int64, lk, c_bool
    implicit none
    private
    public :: format_string

    !> Create a character string representing the value of the provided variable.
    interface format_string
    #:for type, kind in KINDS_TYPES
        module procedure :: format_string_${type[0]}$${kind}$
    #:endfor
    end interface format_string

contains

    #:for type, kind in KINDS_TYPES
    !> Format ${type}$ variable as character sequence
    pure function format_string_${type[0]}$${kind}$(val, format) result(string)
        integer, parameter :: ik = ${kind}$
        ${type}$, intent(in) :: val
        character(len=*), intent(in) :: format
        character(len=:), allocatable :: string
        integer, parameter :: buffer_len = 512
        character(len=buffer_len) :: buffer

        write(buffer, format, iostat=stat) val
        if (stat == 0) then
            string = trim(buffer)
        else
            string = "*"
        end if
    end function format_string_${type[0]}${kind}$
    #:endfor

end module stdlib_format

Hello, if my num2str can be combined with your code, especially the complex type num2str:
(see #337 (comment))

 forlab_num2str.fypp :
 ---------------------- 
 num2str(c):
 (1.00000000,1.00000000)
 (1.00,1.00)
 num2str(i):
 2
 2
 num2str(r):
 1.00000000
 1.00
 forlab_disp.fypp :
 ----------------------
 disp(ones(c)):
          (1.000,1.000)           (1.000,1.000)
          (1.000,1.000)           (1.000,1.000)
 disp(ones(i)):
          1           1
          1           1
 disp(ones(r)):
  1.000       1.000
  1.000       1.000
 disp(l)
          T           T           T
          T           T           T
 ----------------------
 disp(ones(c)):
     (0.1000E-03,0.000)           (1.000,1.000)
          (1.000,1.000)           (1.000,1.000)
 disp(ones(i)):
          1           1
          1           1
 disp(ones(r)):
 0.1000E-03   0.000
  1.000       1.000

This is great @zoziha, I think the display function would make a great addition to stdlib.

disp

Wow, thank you for your approval, I think I will consider perfecting disp routines for stdlib later. If you have any good suggestions, please feel free to put forward them.

num2str?

I think we have implemented the num2str function to a certain extent, and need to add a logical type, which overlaps to a certain extent with your format_string. What do you think is better for this routine name: num2str, string, format_string, to_chars?
Yes, I also want to complete this routine in stdlib, and a little num2str will be used in the disp routine.

function:   num2str(x [, fmt])
subroutine: disp(x [, string])

Hope to receive your reply.

I think the implementation is uncritical, num2str and format_string are implemented quite similarly. I think it will need more work to reach an agreement on the naming of the routine.

If you are interested, feel free to use the format_string template in your forlab project or to propose the routine to stdlib.

Hello, I submitted a PR, which contains disp and format_string, I am not sure whether it is reasonable, welcome to discuss. (see #445)