fortran - 为什么我的程序循环两次?

标签 fortran gfortran

我尝试在 Fortran 中创建一个 toUpper 和 toLower 函数,它们在我的实现中似乎工作得很好;该程序提示用户输入字符串,然后以大写字母和小写字母打印出来。

但是,在我添加了大写函数后,程序两次提示用户输入字符串,我不明白为什么。它似乎有效,但它做了两次。

有人可以告诉我为什么我的程序提示输入两次吗?代码和输出如下。

program stringutils
    character :: words*1000

    print*, 'Enter a string.'
    read(*,'(A)') words

    call toUpper(words)
    print*, 'toUpper: ', trim(words)

    call toLower(words)
    print*, 'toLower: ', trim(words)

    call capitalize(words)
    print*, 'capitalize: ', trim(words)

end program stringutils

subroutine toUpper(string)
    character :: string*1000
    integer :: i, charNum

    do i = 1, len(trim(string))
        charNum = iachar(string(i:i))
        if (charNum >= 97 .and. charNum <= 122) then
            string(i:i) = achar(charNum - 32)
        end if
    end do
end subroutine toUpper

subroutine toLower(string)
    character :: string*1000
    integer :: i, charNum

    do i = 1, len(trim(string))
        charNum = iachar(string(i:i))
        if (charNum >= 65 .and. charNum <= 90) then
            string(i:i) = achar(charNum + 32)
        end if
    end do
end subroutine toLower

subroutine capitalize(string)
    character :: string*1000
    integer :: i

    call toUpper(string(1:1))
    do i = 2, len(trim(string))
        if (iachar(string(i-1:i-1))==32) then
            call toUpper(string(i:i))
        else
            call toLower(string(i:i))
        end if
    end do
end subroutine capitalize

示例输出:

 Enter a string.
this IS a tEsT!
 toUpper: THIS IS A TEST!
 toLower: this is a test!
 capitalize: This Is A Test!
 Enter a string.
why is this running a second time?
 toUpper: WHY IS THIS RUNNING A SECOND TIME?
 toLower: why is this running a second time?
 capitalize: Why Is This Running A Second Time?

我在 Windows 中通过 MinGW 使用 gfortran。

最佳答案

这是一个扩展评论,而不是一个答案......

我不相信你对最初报告的问题原因的解释。我不明白为什么程序会因为一两个错误指定的例程而执行两次。尽管如此,如果多关注现代 Fortran 实践,您的日常工作将会得到很大改善。

您已经编写了一堆例程来操作 1000 个字符的字符串。更好的方法肯定是编写它们来操作作为参数传递的字符串的任意长度的字符串。现代 Fortran(因为我不确定,至少 90 个,可能在那之前)允许传递 假定长度字符 参数,就像这样:

subroutine toUpper(string)
    character(*) :: string
    integer :: i, charNum

    do i = 1, len(trim(string))
        charNum = iachar(string(i:i))
        if (charNum >= 97 .and. charNum <= 122) then
            string(i:i) = achar(charNum - 32)
        end if
    end do
end subroutine toUpper

现在,当调用例程时,它将对 string 中的所有字符进行操作,不多也不少。

我还建议进行许多其他修改。我没有时间详细介绍所有这些内容,但如果您在这里浏览一下,您会发现有关这些主题的几个问题和解答。这是入门套件:

  • 始终使用程序实体的显式声明,在程序(和模块)中不包含隐式声明。这是编写安全程序的第一条基本规则。
  • 将您的例程放入模块中并使用它们。这确保编译器可以并且确实检查您对它们进行的调用在语法上是否有效。
  • 就我个人而言,我会将所有子例程变成函数,并返回输入字符串的大写(或小写)版本。让子例程修改输入字符串并没有什么问题,但是编写函数更容易,例如,有一天您可能想要编写类似 HumpyString = Capitalise(toLower(string))
  • 的内容

关于fortran - 为什么我的程序循环两次?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37955621/

相关文章:

c++ - 将 char 数组从 C++ 传递到 Fortran

fortran - 有没有删除 Fortran 中所有非字母数字的函数?

fortran - 关闭警告 : `Non-conforming tab character` in gfortran

fortran - 如何消除 Fortran 文本字段开头的空格?

c - 无法将数组从 FORTRAN 传递到 C

arrays - 从 Fortran 中的子例程返回分配的字符串数组?

types - 带 MPI 的派生数据类型

delphi - 从 Fortran 调用 Delphi 函数时出现段错误

fortran - 如何查明使用哪个版本的 gfortran 来编译 fortran .mod 文件

optimization - 为什么打开 gfortran 编译器优化后 matmul 变慢?