Fortran 文字列や文字列の配列の置き方

## はじめに

Modern Fortranの文字列の置き方について忘れることが多いので備忘録として記す。  
詳しい内容を知りたければ以下を見るとよい。  
https://fortran-lang.org/learn/quickstart/arrays_strings/#character-strings
https://fortran-lang.org/learn/quickstart/arrays_strings/#array-of-strings
https://qiita.com/implicit_none/items/f582f2d4e10f2655e208

## 文字列について

### 古い書き方

```fortran
program main
    use, intrinsic :: iso_fortran_env
    implicit none
    character(len=30) :: filename

    filename = "abc/aaaa.dat"
    print *, filename
end program main
```

ファイル名などに対して必要だと思われる文字数を決め打ちして`character`型を決める。

### 新しい書き方

```fortran
program main
    use, intrinsic :: iso_fortran_env
    implicit none
    character(:), allocatable :: filename !割り当て可能な文字列
    character(:), allocatable :: filename2 !割り当て可能な文字列

    allocate (character(len=10) :: filename) !明示的に大きさを割り当てる
    filename = 'aaaa/a.txt'

    filename2 = 'aaaa/a.txt' ! 自動的に大きさを割り当てる

    print *, filename
    print *, filename2

end program main
```

代入する直前文字数を決める方法と自動的に大きさを割り当てる方法の２種類がある。  
`filename2`のような使い方が便利である。

## 文字列の配列について

```fortran
program main
    use, intrinsic :: iso_fortran_env
    implicit none

    character(len=10) :: char_list1(2)
    character(len=10) :: char_list2(2)
    character(len=10), allocatable :: char_list3(:)
    character(len=10), allocatable :: char_list4(:)
    integer(int32), parameter :: num = max(len("abc"),len("def"),len("ghi"), len("aaaa"))
    integer(int32) :: num2
    character(:), allocatable :: char_list5(:) !文字列の配列(文字列の大きさも割り当て可能にする)
    character(:), allocatable :: char_list6(:) !文字列の配列(文字列の大きさも割り当て可能にする)
    !character(:), allocatable :: char_list7(2) ! できない

    char_list1(1) = "abc"
    char_list1(2) = "def"

    char_list2 = [character(len=10) :: "abc", "def"] ! 配列にする際は文字数は同じでなくてはならない。


    allocate (char_list3(3)) !明示的に大きさを割り当てる
    char_list3(1) = "abc"
    char_list3(2:3) = [character(len=10) :: "def", "ghij"]

    char_list4 = [character(len=10) :: "abc", "def", "ghi"] ! 自動的に大きさを割り当てる

    allocate (character(len=num) :: char_list5(4)) !明示的に大きさを割り当てる
    char_list5 = [character(len=num) :: "abc", "def", "ghi", "aaaa"]

    char_list6 = [character(len=num) :: "abc", "def", "ghi", "aaaa"] ! 自動的に大きさを割り当てる

    num2 = 10
    !deallocate(char_list6)
    !char_list6 = [character(len=num2) :: "abc", "def", "ghi", "aaaa"] !これはできない

    print *, char_list1
    print *, char_list2
    print *, char_list3
    print *, char_list4
    print *, char_list5
    print *, char_list6
end program main
```

Allocatable arraysも可能。上記のように一部できない構成がある。  
ただしlenに入れる整数は定数でなければならないので、`char_list5`や`char_list6`のようなものは使用しずらいかと思われる。


## 文字列や文字列の配列を仮引数に使用する場合

```fortran
program main
    use, intrinsic :: iso_fortran_env
    implicit none
    character(:), allocatable :: filename
    character(len=10), allocatable :: texts(:)

    filename = 'tmp.txt'
    texts = [character(len=10) :: "abc", "def"]

    call print_txt(filename, texts)

contains
    subroutine print_txt(txt, txt_list)
        implicit none
        character(len=*), intent(in) :: txt !文字列(文字数は任意)
        character(len=*), intent(in) :: txt_list(:) !文字列(文字数は任意)の配列
        integer(int32) :: i

        print *, txt
        do i = 1, size(txt_list)
            print *, trim(txt_list(i))
        end do

    end subroutine print_txt

end program main
```

上記の例のように文字数が任意なもの入れたければ`len`にアスタリスクを入れて使用する。  
文字数が決まっている場合はその文字数を入れる。