Skip to content

Comparison to Other Approaches ​

The lack of built-in string manipulation in Fortran has led to several different solutions over the years. This page compares StringiFor to the three main alternatives identified by Clive Page [1].

The Four Approaches ​

1. Standard character type ​

Fixed-length at compile time. Simple and universally supported, but severely limited:

fortran
character(len=3) :: s
s = 'abcdefgh'   ! silently truncated to 'abc'

2. Deferred-length allocatable character ​

Introduced in Fortran 2003. Removes the fixed-length constraint but array elements must still all have the same length:

fortran
character(len=:), allocatable :: s
character(len=:), allocatable :: arr(:)

s = 'Hello '
s = s // 'World'    ! no trim() needed, length adapts

allocate(character(len=99) :: arr(10))  ! all 10 elements are len=99

3. aniso_varying_string (Ian Harvey's ISO implementation) ​

A derived type wrapping a deferred-length allocatable character, implementing ISO/IEC 1539-2:2000. Solves the array-element problem but has I/O and slicing limitations:

fortran
type(varying_string), allocatable :: arr(:)
allocate(arr(10))   ! elements can have different lengths

4. StringiFor ​

Shares the same philosophy as aniso_varying_string — a derived type wrapping a single character(kind=CK, len=:), allocatable member — but adds an extensive OOP API modelled after Python's string methods.

fortran
type(string), allocatable :: arr(:)
allocate(arr(10))   ! elements can have different lengths

Issue-by-Issue Comparison ​

IssuecharacterDeferred-lengthaniso_varying_stringStringiFor
Fixed length at compile time✗✓✓✓
Silent truncation on assignment✗✓✓✓
trim()-cluttered code✗✓✓✓
Significant trailing spaces✗✓✓✓
Single definition syntax✗✗✓✓
Array allocation (variable lengths)✗✗✓✓
Array initialization✗✗✓✓
I/O support✓✓~~
Substring (slice) notation✓✓~~
Fortran intrinsics as-is✓✓~~

✓ = good support · ~ = partial support · ✗ = bad or no support

Notes on partial I/O support ​

Both aniso_varying_string and StringiFor support I/O through defined I/O type-bound procedures (read(formatted), write(formatted), etc.). The DT edit descriptor (defined I/O) is fully supported in gfortran ≥ 7.1. For simpler portability, the //'' concatenation idiom converts a string to a character on the fly:

fortran
print "(A)", my_string//''

Notes on slice notation ​

Standard slice notation (s(2:5)) cannot be applied to a derived type. StringiFor provides the slice method as equivalent, while chars() returns the whole content as a standard character:

fortran
! Standard character
print "(A)", s(2:5)

! StringiFor equivalent
print "(A)", my_string%slice(first=2, last=5)

StringiFor's Distinctive Features ​

Beyond solving the same issues as aniso_varying_string, StringiFor adds:

  • Number casting — assign any PENF integer or real directly to a string; cast back with to_number(kind=...), or with read_number and an iostat/iomsg error status
  • Python-like text methods — split (optionally keeping the empty fields), join, partition, replace, strip, center, ljust, rjust, expand_tabs, compact, squeeze, transliterate, quote/unquote
  • Character classes — is_alpha, is_alnum, is_digit, is_xdigit, is_punct, is_space
  • File I/O — read_file, write_file, read_line for common file-handling patterns
  • Path manipulation — basedir, basename, extension
  • Case conversion — camelcase, snakecase, startcase, capitalize, swapcase
  • Encoding — Base64 encode/decode via BeFoR64
  • Color output — ANSI terminal colorization via FACE
  • Wildcards — match of *, ?, [...] patterns on strings in memory; glob to list the matching files (Unix)
  • Namespace safety — all functionality is accessible through the single string type; no global namespace pollution unless the overloaded intrinsic interfaces are explicitly imported

References ​

[1] Clive Page, Improved String-handling in Fortran, October 2015.

[2] Ian Harvey, aniso_varying_string, 2016.