2015-10-04 79 views
1

我想要一个程序,使输入字符a(不假定长度)的本地副本b成为可分配的字符数组。我有下面的代码在Fortran中复制字符串失败

program test_copystr 

    character(len=6) :: str 
    str = 'abc' 
    call copystr(str) 

contains 

    subroutine copystr(a) 
     character(len=*), intent(in) :: a 
     !> Local variables 
     integer :: i 
     character, allocatable :: b(:) 
     allocate(b(len_trim(a))) 
     do i=1, len_trim(a) 
     b(i) = a(i:i) 
     end do 
     print *, b 
     b(1:len_trim(a)) = a(1:len_trim(a)) 
     print *, b 
    end subroutine copystr 

end program test_copystr 

在那里我试图在两种不同的方式分配给ab。其结果是

ABC

AAA

我认为这两个任务应该产生相同的输出。任何人都可以解释我的区别? (要编译此代码,我使用gfortran 5.2.0编译器。)

回答

3

如您所知b是一个字符数组,而a是一个标量;当子程序被调用时它是一个6个字符的字符串。这些是不同的事情。该语句

b(1:len_trim(a)) = a(1:len_trim(a)) 

指定在LHS的阵列部分b(1:3),那就是所有b 3层的元件,并且在RHS子串a(1:3)。现在,将长度为3的子字符串分配给单个字符(如b的任何元素)时,Fortran只分配字符串的第一个字符。

在这种情况下,b的每个元素都设置为a的第一个字符。就好像编译器生成3条语句

b(1) = 'abc' 
    b(2) = 'abc' 
    b(3) = 'abc' 

来实现数组赋值。这就是Fortran数组语法对lhs上的数组和rhs上的标量(表达式)所做的操作,它将标量广播给数组中的每个元素。

您使用的第一种方法,循环遍历b的元素和a的字符是使字符数组等同于字符串的常规方法。但你可以试试transfer - 看到我对这个问题的回答Removing whitespace in string