且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

使用延迟字符串来读取用户输入

更新时间:2023-11-13 18:14:10

vincentjs的回答不太对。

b
$ b现代(2003+)Fortran 不允许允许在赋值时自动分配和重新分配字符串,因此一系列语句如
 字符(len = :),allocatable :: string 
...
string ='Hello'
写(*,*)
string ='my friend'
write(*,*)
string ='Hello'// string
write(*,*)

是正确的,它将按预期工作并写出3个不同长度的字符串。至少有一种广泛使用的编译器,即英特尔Fortran编译器,默认情况下不支持2003语义,因此可能会在尝试编译时产生错误。 然而,这个功能在读取字符串时不可用,所以你必须求助于经过测试和测试的(

 字符(len = long):: buffer 
字符(len = :),allocatable ::字符串
...
读取(*,*)缓冲区
string = trim(缓冲区)

不,我不知道为什么语言标准禁止在 read 上自动分配,就是这样。


I would like to use deferred-length character strings in a "simple" manner to read user input. The reason that I want to do this is that I do not want to have to declare the size of a character string before knowing how large the user input will be. I know that there are "complicated" ways to do this. For example, the iso_varying_string module can be used: https://www.fortran.com/iso_varying_string.f95. Also, there is a solution here: Fortran Character Input at Undefined Length. However, I was hoping for something as simple, or almost as simple, as the following:

program main

  character(len = :), allocatable :: my_string
  read(*, '(a)') my_string
  write(*,'(a)') my_string
  print *, allocated(my_string), len(my_string)

end program

When I run this program, the output is:

./a.out
here is the user input

F       32765

Notice that there is no output from write(*,'(a)') my_string. Why?

Also, my_string has not been allocated. Why?

Why isn't this a simple feature of Fortran? Do other languages have this simple feature? Am I lacking some basic understanding about this issue in general?

vincentjs's answer isn't quite right.

Modern (2003+) Fortran does allow automatic allocation and re-allocation of strings on assignment, so a sequence of statements such as this

character(len=:), allocatable :: string
...
string = 'Hello'
write(*,*)
string = 'my friend'
write(*,*)
string = 'Hello '//string
write(*,*)

is correct and will work as expected and write out 3 strings of different lengths. At least one compiler in widespread use, the Intel Fortran compiler, does not engage 2003 semantics by default so may raise an error on trying to compile this. Refer to the documentation for the setting to use Fortran 2003.

However, this feature is not available when reading a string so you have to resort to the tried and tested (aka old-fashioned if you prefer) approach of declaring a buffer of sufficient size for any input and of then assigning the allocatable variable. Like this:

character(len=long) :: buffer
character(len=:), allocatable :: string
...
read(*,*) buffer
string = trim(buffer)

No, I don't know why the language standard forbids automatic allocation on read, just that it does.