0
program Test

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

对于每一个字符,我都用凯瑟密码加密它

计算

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,并执行它,它就可以工作。但我希望能够在不定义长度的情况下做到这一点。有什么办法吗?

4

3 回答 3

1

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

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

就在读取输入的上下文中避免固定长度的字符串而言 - Fortran 2003 引入了延迟长度字符,这在这里有很大帮助。否则,请参阅读取长度未知的字符串以了解 Fortran 95 的可能性。一个复杂的问题是您正在从控制台读取,因此退格语句可能不起作用。解决此问题的方法与链接方法类似,但需要在确定输入记录长度的同时将输入字符串分段构建为可分配的字符数组。然后使用序列关联将该数组转换为正确长度的标量。评论或再次询问您是否需要更多详细信息。

于 2013-02-15T02:09:52.603 回答
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”返回的值等于位于模块“iso_fortran_env”中的整数常量“IOSTAT_EOR”:

use iso_fortran_env, only : IOSTAT_EOR

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

character(len = :), allocatable :: input

在“read”语句中,“advance = 'no'”允许一次读入几个字符。“缓冲区”的大小决定了要读取的字符数(在我们的例子中为 1)。

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

如果“iostat”返回“0”,则没有错误,也没有 eor。在这种情况下,应将“缓冲区”字符添加到“输入”字符串中。最终,这一步分配了一个“新”输入,其大小等于“旧”输入 + 缓冲区字符的大小。新分配的输入包含来自旧输入的字符 + 缓冲区字符。

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

如果“iostat”返回一个 eor 值,则退出 do 循环。

case(IOSTAT_EOR)
  exit
于 2015-06-04T00:17:28.327 回答
0

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

于 2013-02-15T01:49:30.943 回答