未定义长度的Fortran字符输入

时间:2013-02-15 00:56:56

标签: fortran fortran95

program Test

implicit none
character (LEN=100) :: input
character (LEN=100) :: output
print *,"Please input your message: "
read *, input

对于每个角色,我都会在Ceaser的密码中加密它

计算

print *,"This is the output: "
write (*,"(2a)") "Message = ", out

end program Test

这不完全有效。

对于输入中的每个字符,我使用modulo(iachar())函数进行转换。它一直工作到打印,我跟着调试,加密很好。 但输出问题在于LEN = 100。 do循环将经历100次将不存在的字符转换为垃圾,在输出处以UNDEFINED TYPE打破程序。

因此,如果我输入“test”,它将加密CBNC * GARBAGE-TO-100 *而不输出。如果我将长度定义为4,那么它就可以了。但我希望能够在不定义长度的情况下做到这一点。有什么方法吗?

3 个答案:

答案 0 :(得分:1)

read语句应该用空格填充input到变量的全长(100个字符),而不是添加“garbage”。 LEN_TRIM内部函数将给出变量值的显着长度 - 即不包括尾随空白的长度。在打印输出字符串时,您可能需要记住输入字符串的这个有效长度。

(注意列表定向输入的规则(由read语句中的*表示)可能有点令人惊讶 - “(A)”的格式可能更强大,具体取决于您想要的行为。)

在读取输入的上下文中避免固定长度字符串方面 - Fortran 2003引入了延迟长度字符,这在这里有很大帮助。否则请参阅Reading a character string of unknown length了解Fortran 95的可能性。一个复杂因素是您正在从控制台读取,因此退格语句可能无效。对此进行的处理遵循与链接类似的方法,但需要在确定输入记录长度的同时将输入字符串分段构建为可分配的字符数组。然后使用序列关联将该数组转换为正确长度的标量。如果您想了解更多详情,请再次提出评论或询问。

答案 1 :(得分:1)

以下代码读取未指定长度的用户输入字符串。请注意,它需要一个支持延迟长度字符串的编译器:character(len = :)。 Fortran 2003中引入了延迟长度的字符串。

program test

  use iso_fortran_env, only : IOSTAT_EOR
  implicit none

  integer :: io_number
  character(len = 1) :: buffer
  character(len = :), allocatable :: input, output

  input = ""
  print *, "Please input your message."

  do
    read(unit = *, fmt = '(a)', advance = "no", iostat = io_number) buffer
    select case (io_number)
    case(0)                       
      input = input // buffer     
    case(IOSTAT_EOR)
      exit
    end select
  end do

  allocate(character(len=(len(input))) :: output)

  ! Now use "input" and "output" with the ciphering subroutine/function.

end program test

说明

这个想法是在寻找记录结束(eor)条件的同时一次读取一个字符。 eor条件是由用户按下" return"键。 " iostat"选项可用于寻找eor。 " iostat"返回的值等于整数常数" IOSTAT_EOR"位于模块" iso_fortran_env":

use iso_fortran_env, only : IOSTAT_EOR

我们声明一个延迟长度的字符串来获取未知长度的用户输入:

character(len = :), allocatable :: input

在"阅读"声明," advance =' no'"允许一次读入几个字符。 "缓冲区"的大小确定要读入的字符数(在我们的例子中为1)。

read(unit = *, fmt = '(a)', advance = "no", iostat = io_number) buffer

如果" iostat"返回" 0",然后没有错误也没有eor。在这种情况下,"缓冲区"字符应添加到"输入"串。最后,这一步将分配一个新的"输入大小为" old"输入+缓冲区字符。新分配的输入包含旧输入+缓冲区字符中的字符。

select case (io_number)
case(0)                       
  input = input // buffer

如果" iostat"返回eor值,然后退出do循环。

case(IOSTAT_EOR)
  exit

答案 2 :(得分:0)

标准的Fortran字符串是固定长度,右边用空格填充。如果您的输入字符串永远不会有尾随空白,则解决方案很简单:使用Fortran内部函数len_trim查找字符串的非空白长度并仅处理这些字符。另一种方法是使用新功能,可分配字符串......这提供了可变长度字符串。如果不接受字符串末尾的空格,您可能会更容易使用len_trim