计算String中的Array元素

时间:2017-03-20 13:45:53

标签: arrays io fortran

我正在尝试将包含未知数量整数的字符串读入Fortran数组。

string = "2  5,7 6 0"

解析字符串本身是有效的,因为我知道数组的最大可能大小。分隔符可以变化,例如空格,制表符逗号或它们的组合 但是,我如何计算我读过多少元素? 目前我的代码如下:

program count_string_elements
  implicit none
  character(len=50) :: string
  integer :: i, count, imax, ios
  integer,allocatable :: tmp_arr(:)

  imax = 20
  allocate(tmp_arr(imax))

  string = "2  5,7 6 0"
  read(unit=string, fmt=*, iostat=ios) (tmp_arr(i), i=1,imax)
  print *, tmp_arr

  deallocate(tmp_arr)
end program

输出为

2    5    7    6    0    0    0    0    0    0

将其设置为默认值(如-1,0)或其他内容不是一个选项,因为我无法排除它们在字符串中。

有没有办法中止阅读,以便我包含元素的数量(或元素的数量+ 1)?

  

更新   我通过将代码扩展到上面找到了一种方法。

program count_string_elements
  implicit none
  character(len=50) :: string
  integer :: i, cnt, imax, ios
  integer,allocatable :: tmp_arr(:)
  character(len=50) :: str_arr(:)
  imax = 20
  allocate(tmp_arr(imax), str_arr(imax))

  string = "2  5,7 6 0"
  cnt = 0
  read(unit=string, fmt=*, iostat=ios) (str_arr(i), i=1,imax)
  do i = 1, imax
    if(len_trim(str_arr(i)) == 50) cycle
    cnt = cnt + 1
    read(str_arr(i),*) tmp_arr(cnt)
  end do
  print *, tmp_arr(:cnt)

  deallocate(str_arr, tmp_arr)
end program

但是可能有更好的方法来做到这一点。

1 个答案:

答案 0 :(得分:0)

有许多不同的可能整数值。它不应该太难,这取决于您必须找到一个不太可能属于数据集的数据类型,并将其用作虚拟数据。

那就是说,我解决这个问题的方法(快速和肮脏)就是遍历整个字符串并计算非数字和数字之间的转换次数。

见这个例子:

program arb_array

    implicit none
    character(len=30) :: test_string
    integer :: imax
    integer :: array(10)

    test_string = "2  5,7 6 0"

    imax = count_integers(test_string)

    read(test_string, *) array(:imax)
    print*, imax, array(:imax)

contains

    function is_digit(c)
        implicit none
        character, intent(in) :: c
        logical :: is_digit
        is_digit = ((ichar(c) >= ichar('0')) .and. (ichar(c) <= ichar('9')))
        return
    end function is_digit

    function count_integers(string) result(imax)
        implicit none
        character(len=*), intent(in) :: string
        integer :: imax
        integer :: i

        imax=0
        i = 1
        counter_loop : do
            do while (.not. is_digit(string(i:i)))
                i = i + 1
                if (i > len(string)) exit counter_loop
            end do
            imax = imax+1
            do while (is_digit(string(i:i)))
                i = i + 1
                if (i > len(string)) exit counter_loop
            end do
        end do counter_loop

    end function count_integers
end program arb_array