Files
Fortran-95-2003-Program-3rd…/20210510-第10章习题.f90
2025-09-25 16:46:47 +08:00

641 lines
33 KiB
Fortran
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

! ==============================================================================
! 通过 gfortran ./test.f90 -o ./run && ./run 运行
! 程序名:
! 第10章习题及书上例题
! 目的:
!
! 修订记录:
! 日期 编程者 改动描述
! =================== ============= =====================================
! 2021-05-10 17:15:53 Sola 测验10-1 4 判断星期几
! 2021-05-10 17:22:01 Sola 测验10-1 5 字符串反序
! 2021-05-10 17:33:13 Sola 测验10-1 6-8 测试字符
! 2021-05-10 18:14:05 Sola 例题10-3 转换输出数值格式
! 2021-05-10 21:58:38 Sola 测验10-2 3
! 2021-05-11 14:30:07 Sola 习题10-4 字符串转大写
! 2021-05-11 15:00:14 Sola 习题10-5 字符串转小写
! 2021-05-11 16:03:39 Sola 习题10-8 首字母大写
! 2021-05-11 17:39:18 Sola 习题10-9 10-8可变函数版(话说直接写的就是可变函数版本的...)
! 2021-05-11 17:39:48 Sola 习题10-10 检测字符中实际字符数
! 2021-05-11 18:16:41 Sola 习题10-11 检测第一个和最后一个非空字符位置(话说上一题的函数改一改不就是了)
! 2021-05-11 19:10:54 Sola 习题10-12 输入参数文件
! 2021-05-11 21:51:02 Sola 习题10-13 直方图 ??? 这是什么鬼需求
! 2021-05-12 11:28:44 Sola 习题10-14 随机数直方图
! 2021-05-12 13:18:26 Sola 习题10-15 拷贝文件去除注释
! 程序结构:
!
! ==============================================================================
! 模块:
module Chapter10
implicit none
! 数据字典
! 声明常数
REAL, PARAMETER :: PI=3.14159265 ! PI值
REAL, PARAMETER :: e=2.718281828459 ! 自然对数
INTEGER, PARAMETER :: arrayLength=20 ! 数组基准长度
! 声明变量
! 创建显式接口
contains
end module Chapter10
! ==============================================================================
! 主程序:
program ProName
! use ModName
implicit none
! 数据字典
! 声明常量
! 声明变量
! 变量初始化
! 数据输入
! 运算过程
! 结果输出
! call Exercises10_1_4
! call Exercises10_1_5
! call Exercises10_1_6_8
! call Example10_3
! call Exercises10_2_3
! call Exercises10_4
! call Exercises10_10
! call Exercises10_12
! call Exercises10_13
! call Exercises10_14
call Exercises10_15
end program ProName
! ==============================================================================
! 子程序
! subroutine SubName(varName1,varName2)
! use MouName
! implicit none
! Type, intent(inout) :: varName
! end subroutine SubName
! ==============================================================================
! 函数
! function FunName(varName1,varName2)
! use MouName
! implicit none
! end function FunName
! ==============================================================================
! 测试10-1 4 判断星期几
subroutine Exercises10_1_4
implicit none
integer :: i
write(*,*) (day(i), i = 7, 1, -1)
contains
function day(iday)
integer, intent(in) :: iday
character(len=3) :: day
character(len=3), dimension(7) :: days=(/'SUN', 'MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT'/)
if ( (iday>=1) .and. (iday<=7) ) then
day = days(iday)
end if
end function day
end subroutine Exercises10_1_4
! 测试10-1 5 字符串反序
subroutine Exercises10_1_5
implicit none
write(*,*) swap_string('Hello World!')
contains
function swap_string(string)
character(len=*), intent(in) :: string
character(len=len(string)) :: swap_string
integer :: length, i
length = len(string)
do i = 1, length
swap_string(length-i+1: length-i+1) = string(i: i)
end do
end function swap_string
end subroutine Exercises10_1_5
! 测验10-1 6-8
subroutine Exercises10_1_6_8
implicit none
call sub1
call sub2
call sub3
contains
subroutine sub1
character(len=20) :: last='JOHNSON'
character(len=20) :: first='JAMES'
character :: middle_initial='R'
character(len=42) :: name
write(*,*) middle_initial
name = last //', '//first//middle_initial
write(*,*) name
end subroutine sub1
subroutine sub2
character(len=4) :: a='123'
character(len=12) :: b
b = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
write(*,*) a, ', ', b
b(5: 8) = a(2: 3)
write(*,*) a, ', ', b
end subroutine sub2
subroutine sub3
character(len=80) :: line
integer :: ipos1, ipos2, ipos3, ipos4
line = 'This is a test line containing some input data!'
ipos1 = index(line, 'in')
ipos2 = index(line, 'Test')
ipos3 = index(line, 't l')
ipos4 = index(line, 'in', .TRUE.)
write(*,*) ipos1, ipos2, ipos3, ipos4
end subroutine sub3
end subroutine Exercises10_1_6_8
! 例题10-3 转换输出数值格式
subroutine Example10_3
implicit none
real :: input
character(len=1) :: runLevel
outer:do
write(*, *) '请输入数值:'
read(*, *) input
write(*, *) '输出的结果为:', num2str(input)
inner:do
write(*, *) '是否接着输入下一个数值? 继续(Y)/结束(N)'
read(*, *) runLevel
if ( runLevel == 'Y' .or. runLevel == 'y' ) then
exit inner
else if ( runLevel == 'N' .or. runLevel == 'n' ) then
exit outer
else
write(*,*) '非法输入! 请重新输入!'
end if
end do inner
end do outer
contains
function num2str(num)
character(len=12) :: num2str ! 函数输出类型
real, intent(in) :: num ! 输入实数
if ( abs(num) <= 9999999. .and. abs(num) >= 0.01 .or. num == 0 ) then
write(num2str, '(F12.4)') num
else
write(num2str, '(ES12.5)') num
end if
end function num2str
end subroutine Example10_3
! 测验10-2 3
subroutine Exercises10_2_3
implicit none
character(len=30) :: line = '123456789012345678901234567890'
character(len=30) :: fmt = '(3X, I6, 12X, I3, F6.2)'
integer :: ival1, ival2
real :: rval3
read (line, fmt) ival1, ival2, rval3
write(*,*) ival1, ival2, rval3
end subroutine Exercises10_2_3
! 习题10-4 字符串转大写
subroutine Exercises10_4
implicit none
character(len=132) :: input
character :: runLevel
outer:do
write(*, *) '请输入一段字符小于132字包含空格字符请用引号括起'
read(*, *) input
write(*, *) '转换大写结果为:', Ucase(input)
write(*, *) '转换小写结果为:', Lcase(input)
write(*, *) '首字符大写结果为:', Caps(input)
inner:do
write(*, *) '是否接着转换下一个字符串? 继续(Y)/结束(N)'
read(*, *) runLevel
if ( runLevel == 'Y' .or. runLevel == 'y' ) then
exit inner
else if ( runLevel == 'N' .or. runLevel == 'n' ) then
exit outer
else
write(*,*) '非法输入! 请重新输入!'
end if
end do inner
end do outer
contains
! 转换为大写
function Ucase(str)
character(len=*), intent(in) :: str ! 定义输入字符串
character(len=len(str)) :: ucase ! 定义函数类型
integer :: i ! 循环参数
do i = 1, len(str) ! 对输入每个字符循环
if ( lge(str(i: i), 'a') .and. lle(str(i: i), 'z') ) then ! 如果字符在a~z中
Ucase(i: i) = achar( iachar(str(i: i)) - 32 ) ! 输出大写
else
Ucase(i: i) = str(i: i) ! 如果不在, 输出原字符
end if
end do
end function Ucase
! 转换为小写
function Lcase(str)
character(len=*), intent(in) :: str ! 定义输入字符串
character(len=len(str)) :: Lcase ! 定义函数类型
integer :: i ! 循环参数
do i = 1, len(str) ! 对每个输入字符循环
if ( lge(str(i: i), 'A') .and. lle(str(i: i), 'Z') ) then ! 如果字符在A~Z中
Lcase(i: i) = achar( iachar(str(i: i)) + 32 ) ! 输出小写
else
Lcase(i: i) = str(i: i) ! 如果不再, 输出原字符
end if
end do
end function Lcase
! 首字符大写
! 情况可能如下:
! 1. 小写字母, runLevel .eqv. .TRUE. 转换为大写, runLevel = .FALSE.
! 2. 小写字母, runLevel .eqv. .FALSE. 不变
! 3. 大写字母, runLevel .eqv. .TRUE. 不变, runLevel = .FALSE.
! 4. 大写字母, runLevel .eqv. .FALSE. 转换为小写
! 5. 非字符, runLevel = .TRUE.
function Caps(str)
character(len=*), intent(in) :: str ! 输入字符
character(len=len(str)) :: Caps ! 定义函数类型
integer :: i ! 循环参数
logical :: runLevel ! 运行级别(判断是否为首字母)
runLevel = .TRUE. ! 初始化运行级别
do i = 1, len(str) ! 遍历每个字符
if ( lge(str(i: i), 'a') .and. lle(str(i: i), 'z') .and. ( runLevel .eqv. .TRUE. ) ) then ! 小写字母为首字母
Caps(i: i) = achar( iachar(str(i: i)) - 32 ) ! 转换为大写字母
runLevel = .FALSE. ! 下一个字符非首字母
elseif ( lge(str(i: i), 'a') .and. lle(str(i: i), 'z') .and. ( runLevel .eqv. .FALSE. ) ) then ! 小写字母非首字母
Caps(i: i) = str(i: i) ! 不改变字符
elseif ( lge(str(i: i), 'A') .and. lle(str(i: i), 'Z') .and. ( runLevel .eqv. .TRUE. ) ) then ! 大写字母为首字母
Caps(i: i) = str(i: i) ! 不改变字符
runLevel = .FALSE. ! 下一个字符非首字母
elseif ( lge(str(i: i), 'A') .and. lle(str(i: i), 'Z') .and. ( runLevel .eqv. .FALSE. ) ) then ! 大写字母非首字母
Caps(i: i) = achar( iachar(str(i: i)) + 32 ) ! 转换为小写字母
elseif ( lge(str(i: i), '0') .and. lle(str(i: i), '9') ) then ! 如果是数字
Caps(i: i) = str(i: i) ! 不改变字符
runLevel = .FALSE. ! 下一个字符不是首字母
else ! 非字母
Caps(i: i) = str(i: i) ! 不改变字符
runLevel = .TRUE. ! 下一个字符是首字母(如果是字母)
end if
end do
end function Caps
end subroutine Exercises10_4
! 习题10-10 检测字符串中实际字符数量
subroutine Exercises10_10
implicit none
character(len=132) :: input
character :: runLevel
integer :: errorLevel
integer :: firstNonBlank, lastNonBlank
outer:do
write(*, *) '请输入一段字符小于132字包含空格字符请用引号括起'
read(*, *) input
write(*, *) '该字符的长度为:', LenUsed(input)
write(*, *) '该字符的允许长度为:', len(input)
write(*, *) '该字符除去尾部空格的长度为:', len_trim(input)
call NonBlank(input, firstNonBlank, lastNonBlank, errorLevel)
if ( errorLevel /= 0 ) then
write(*, *) '错误! 没有输入字符或输入字符为空!'
else
write(*, *) '第一个非空字符在第', firstNonBlank, '位, 最后一个非空字符在第', lastNonBlank, '位。'
end if
inner:do
write(*, *) '是否接着计算下一个字符串? 继续(Y)/结束(N)'
read(*, *) runLevel
if ( runLevel == 'Y' .or. runLevel == 'y' ) then
exit inner
else if ( runLevel == 'N' .or. runLevel == 'n' ) then
exit outer
else
write(*,*) '非法输入! 请重新输入!'
end if
end do inner
end do outer
contains
! 习题10-10 判断字符串中有多少字符
function LenUsed(str)
character(len=*), intent(in) :: str ! 输入字符串
integer :: LenUsed ! 定义函数返回类型
integer :: i ! 循环参数
integer :: firstSpace, lastSpace ! 首位空白字符位置
firstSpace = 0 ! 初始化变量
lastSpace = len(str)
do i = 1, lastSpace ! 判断字符串首最后一个空白字符位置
if ( str(i:i) == ' ' ) then
firstSpace = i
else
exit
end if
end do
if ( firstSpace /= lastSpace ) then ! 如果不是全部都是空白字符
do i = lastSpace, firstSpace+1, -1 ! 判断字符串尾第一个空白字符位置
if ( str(i:i) == ' ' ) then
lastSpace = i
else
exit
end if
end do
LenUsed = lastSpace - firstSpace - 1 ! 判断字符串实际使用长度
else
LenUsed = 0 ! 如果全部都是空白字符, 则长度为0
end if
end function LenUsed
! 习题10-11 判断字符串第一个和最后一个空白字符位置
subroutine NonBlank(str, firstNonBlank, lastNonBlank, errorLevel)
character(len=*), intent(in) :: str ! 输入字符串
integer :: i ! 循环参数
integer, intent(out) :: firstNonBlank, lastNonBlank ! 首位空白字符位置
integer, intent(out) :: errorLevel
firstNonBlank = len(str) ! 初始化变量
lastNonBlank = 0
do i = firstNonBlank, 1, -1 ! 判断字符串最后一个非空白位置
if ( .not. str(i:i) == ' ' ) then
lastNonBlank = i
exit
end if
end do
if ( lastNonBlank /= 0 ) then ! 如果不是全部都是空白字符
do i = 1, lastNonBlank ! 判断字符串第一个空白字符位置
if ( .not. str(i:i) == ' ' ) then
firstNonBlank = i
exit
end if
end do
errorLevel = 0
else
firstNonBlank = 0 ! 如果全部都是空白字符, 则位置为0
errorLevel = 1
end if
end subroutine NonBlank
end subroutine Exercises10_10
! 习题10-12 输入参数文件
subroutine Exercises10_12
implicit none
character(len=132) :: str
real :: start, stop, dt
logical :: plot
integer :: errorLevel
open(unit=1, status='scratch', iostat=errorLevel) ! 打开文件并输入数据
if ( errorLevel /= 0 ) stop "打开临时文件失败"
write(1, '(A)') &
&"start=0.0",&
&"stop=10.0",&
&"dt=0.2",&
&"plot on",&
&" ",&
&" "
rewind(unit=1, iostat=errorLevel) ! 回到第一行
if ( errorLevel /= 0 ) stop "操作临时文件失败"
do ! 读取文件知道文件末尾
read(1, '(A)', iostat=errorLevel) str ! 将内容赋值给字符串
if ( errorLevel /= 0 ) exit ! 判断是否到达文件末尾
call InputData(str, start, stop, dt, plot) ! 读取值
end do
write(*, *) start, stop, dt, plot ! 显示当前读取到的值
close(unit=1, iostat=errorLevel) ! 关闭临时文件
if ( errorLevel /= 0 ) stop "关闭临时文件失败" ! 检测关闭状态
contains
subroutine InputData(str, start, stop, dt, plot) ! 读取值子程序
character(len=*), intent(inout) :: str ! 输入的字符串
real, intent(out) :: start, stop, dt ! 输出数值
integer :: tempLoc ! 临时保存位置的变量
integer :: equLoc, length ! 等号位置及字符串长度
logical :: plot ! 输出逻辑值
equLoc = index(str, '=') ! 得到等号位置
length = len(str) ! 得到字符串长度
if ( equLoc == 0 ) then ! 如果没有等号
tempLoc = index( Ucase(str), 'PLOT') ! 检测全大写字符串中是否有PLOT字符
if ( tempLoc /= 0 ) then ! 如果有
if ( index(Ucase(str(1: length)), 'ON') /= 0 ) then ! 判断PLOT状态并赋值
plot = .TRUE.
elseif ( index(Ucase(str(1: length)), 'OFF') /= 0) then
plot = .FALSE.
end if
end if
return
end if
tempLoc = index( Ucase(str), 'START') ! 判断是否是START变量
if ( tempLoc /= 0 .and. tempLoc < equLoc ) then ! 如果是
write(str, '(A)') str(equLoc+1: length) ! 将值部分读入字符串
read(str, *) start ! 读取值, 接下来相同
return
end if
tempLoc = index( Ucase(str), 'STOP')
if ( tempLoc /= 0 .and. tempLoc < equLoc ) then
write(str, '(A)') str(equLoc+1: length)
read(str, *) stop
return
end if
tempLoc = index( Ucase(str), 'DT')
if ( tempLoc /= 0 .and. tempLoc < equLoc ) then
write(str, '(A)') str(equLoc+1: length)
read(str, *) dt
return
end if
end subroutine InputData
! 转换为大写
function Ucase(str)
character(len=*), intent(in) :: str ! 定义输入字符串
character(len=len(str)) :: ucase ! 定义函数类型
integer :: i ! 循环参数
do i = 1, len(str) ! 对输入每个字符循环
if ( lge(str(i: i), 'a') .and. lle(str(i: i), 'z') ) then ! 如果字符在a~z中
Ucase(i: i) = achar( iachar(str(i: i)) - 32 ) ! 输出大写
else
Ucase(i: i) = str(i: i) ! 如果不在, 输出原字符
end if
end do
end function Ucase
end subroutine Exercises10_12
! 习题10-13 直方图 ??? 这是什么鬼需求
! 基本逻辑如下:
! 1. 首先打开一个临时文件, 并向其中输入数据
! 2. 读取数据, 并向数组中填入相关值
! 3. 依据数据, 构建一个二维数组, 并模拟图表构成
! 4. 打印这个数组, 模拟直方图的形式
subroutine Exercises10_13
implicit none
integer :: errorLevel
character(len=6), dimension(7) :: arrayName ! 类名
integer, dimension(7) :: arrayValue ! 类值
arrayName = (/'100~95', '94~90 ', '89~85 ', '84~80 ', '79~75 ', '74~70 ', '69~65 '/) ! 定义类名
arrayValue = (/3, 6, 9, 7, 4, 2, 1/) ! 定义类值
write(*,*) ' Form 10.13 学生成绩分布直方图' ! 输出标题
call DrawHistogram(arrayName, arrayValue, errorLevel) ! 绘图
contains
! 直方图绘制
subroutine DrawHistogram(arrayName, arrayValue, errorLevel)
character(len=*), dimension(:), intent(in) :: arrayName ! 输入类名
integer, dimension(:), intent(in) :: arrayValue ! 输入类值
integer, intent(out) :: errorLevel ! 错误码
character(len=max(maxval(len_trim(arrayName))+1, 6)), allocatable, dimension(:, :) :: arrayDraw ! 绘图矩阵
integer :: temp, length ! 范围边界
character(len=max(maxval(len_trim(arrayName))+1, 6)) :: bar, line ! 绘制形状
integer :: i ! 循环参数
if ( size(arrayName, 1) /= size(arrayValue, 1) ) then ! 如果类名和值数量不匹配, 报错并返回
errorLevel = 1
return
end if
length = size(arrayValue, 1) ! 获取图表类数目
! temp = 1 ! 初始化类值最大值位置
! do i = 2, length ! 获取类值最大值位置
! if ( arrayValue(i) > arrayValue(temp) ) then
! temp = i
! end if
! end do
! temp = arrayValue(temp) ! 获取最大类值(话说为啥不直接用maxval函数)
temp = maxval(arrayValue) ! 获取最大类值
bar = '' ! 初始化形状
do i = 1, len(bar)-2
bar(i: i) = '%' ! 形成形状(用于表示直方图)
end do
do i = 1, len(line)
line(i: i) = '_' ! 用于显示图表下边界
end do
allocate(arrayDraw(temp+4, length+1), stat=errorLevel) ! 定义数组
if (errorLevel /= 0) print *, "arrayDraw: Allocation request denied"
arrayDraw = '' ! 初始化绘制数组
do i = 1, temp + 3
write(arrayDraw(i, 1)(1: 3), '(I3)') temp + 3 - i ! 绘制数组坐标轴纵轴值
end do
do i = 1, temp + 3
arrayDraw(i, 1)(len(bar)-1:len(bar)) = '| ' ! 绘制数组坐标轴纵轴边界
end do
arrayDraw(temp+3, 1)(len(bar)-1:len(bar)) = '|_' ! 绘制数组坐标轴零点边界
do i = temp-2, 1, -5
arrayDraw(i, 1)(len(bar)-1:len(bar)) = '|-' ! 绘制数组坐标轴纵轴刻度
end do
arrayDraw(temp+3, 2: length+1) = line ! 绘制数组坐标轴横轴
write(arrayDraw(temp+4, 2:size(arrayName, 1)+1), '(A)') (trim(arrayName(i)), i = 1, size(arrayName, 1)) ! 绘制数组坐标轴横轴类名
do i = 1, size(arrayName, 1)
arrayDraw(temp+3-arrayValue(i):temp+2, i+1) = bar ! 绘制数组直方图
end do
do i = 1, temp + 4
write(*, '(100A)') arrayDraw(i, :) ! 打印绘制数组
end do
if (allocated(arrayDraw)) deallocate(arrayDraw, stat=errorLevel) ! 释放数组
if (errorLevel /= 0) print *, "arrayDraw: Deallocation request denied"
errorLevel = 0 ! 设定错误等级为0
end subroutine DrawHistogram
end subroutine Exercises10_13
! 习题10-14 随机数直方图
module ran001
implicit none
integer :: n = 12345
end module ran001
subroutine Exercises10_14
implicit none
integer :: i
integer :: errorLevel
real :: randomValue
character(len=9), dimension(20) :: arrayName ! 类名
integer, dimension(20) :: arrayValue ! 类值
write(*,*) ' Form 10.14 随机数分布直方图' ! 输出标题
arrayName = (/&
&'0.00~0.05', '0.05~0.10', '0.10~0.15', '0.15~0.20', &
&'0.20~0.25', '0.25~0.30', '0.30~0.35', '0.35~0.40', &
&'0.40~0.45', '0.45~0.50', '0.50~0.55', '0.55~0.60', &
&'0.60~0.65', '0.65~0.70', '0.70~0.75', '0.75~0.80', &
&'0.80~0.85', '0.85~0.90', '0.90~0.95', '0.95~1.00'/) ! 定义类名
call seed0(12346.)
arrayValue = 0
do i = 1, 20000
call random(randomValue)
arrayValue(int(randomValue*20+1)) = arrayValue(int(randomValue*20+1)) + 1
end do
call DrawHistogram(arrayName, arrayValue, errorLevel) ! 绘图
contains
! 直方图绘制
subroutine DrawHistogram(arrayName, arrayValue, errorLevel)
character(len=*), dimension(:), intent(in) :: arrayName ! 输入类名
integer, dimension(:), intent(in) :: arrayValue ! 输入类值
integer, intent(out) :: errorLevel ! 错误码
character(len=max(maxval(len_trim(arrayName))+1, 7)), allocatable, dimension(:, :) :: arrayDraw ! 绘图矩阵
integer :: temp, length ! 范围边界
character(len=max(maxval(len_trim(arrayName))+1, 7)) :: bar, line ! 绘制形状
integer :: i ! 循环参数
integer :: maxValue ! 最大值
if ( size(arrayName, 1) /= size(arrayValue, 1) ) then ! 如果类名和值数量不匹配, 报错并返回
errorLevel = 1
return
end if
length = size(arrayValue, 1) ! 获取图表类数目
temp = maxval(arrayValue) ! 获取最大类值
bar = '' ! 初始化形状
do i = 1, len(bar)-2
bar(i: i) = '%' ! 形成形状(用于表示直方图)
end do
do i = 1, len(line)
line(i: i) = '_' ! 用于显示图表下边界
end do
allocate(arrayDraw(14, length+1), stat=errorLevel) ! 定义数组
if (errorLevel /= 0) print *, "arrayDraw: Allocation request denied"
arrayDraw = '' ! 初始化绘制数组
maxValue = maxval(arrayValue)
do i = 1, 13
write(arrayDraw(i, 1)(1: 4), '(I4)') nint(real(maxValue)*(13. - real(i))/10.) ! 绘制数组坐标轴纵轴值
end do
do i = 1, 12
arrayDraw(i, 1)(len(bar)-2:len(bar)) = '| ' ! 绘制数组坐标轴纵轴边界
end do
arrayDraw(13, 1)(len(bar)-2:len(bar)) = '|__' ! 绘制数组坐标轴零点边界
do i = 8, 1, -5
arrayDraw(i, 1)(len(bar)-2:len(bar)) = '|- ' ! 绘制数组坐标轴纵轴刻度
end do
arrayDraw(13, 2: length+1) = line ! 绘制数组坐标轴横轴
write(arrayDraw(14, 2:size(arrayName, 1)+1), '(A)') (trim(arrayName(i)), i = 1, size(arrayName, 1)) ! 绘制数组坐标轴横轴类名
do i = 1, size(arrayName, 1)
arrayDraw(13-nint(real(arrayValue(i))*10./real(maxValue)):12, i+1) = bar ! 绘制数组直方图
end do
do i = 1, 14
write(*, '(100A)') arrayDraw(i, :) ! 打印绘制数组
end do
if (allocated(arrayDraw)) deallocate(arrayDraw, stat=errorLevel) ! 释放数组
if (errorLevel /= 0) print *, "arrayDraw: Deallocation request denied"
errorLevel = 0 ! 设定错误等级为0
end subroutine DrawHistogram
subroutine seed0(iseed)
use ran001
real, intent(in) :: iseed
n = abs(iseed)
end subroutine seed0
subroutine random(ran)
use ran001
real, intent(inout) :: ran
n = mod(8121*n+28411,134456)
ran = real(n)/134456
end subroutine random
end subroutine Exercises10_14
! 习题10-15 拷贝文件去除注释
subroutine Exercises10_15
implicit none
character(len=132) :: str
integer :: errorLevel
open(unit=1, status='scratch', iostat=errorLevel)
if ( errorLevel /= 0 ) stop ""
write(1, '(A)') &
&"subroutine DrawHistogram(arrayName, arrayValue, errorLevel)'!'", &
&"character(len=*), dimension(:), intent(in) :: arrayName ! 输入类名", &
&"integer, dimension(:), intent(in) :: arrayValue ! 输入类值", &
&"integer, intent(out) :: errorLevel ! 错误码", &
&"character(len=max(maxval(len_trim(arrayName))+1, 7)), allocatable, dimension(:, :) :: arrayDraw ! 绘图矩阵", &
&"integer :: temp, length ! 范围边界", &
&"character(len=max(maxval(len_trim(arrayName))+1, 7)) :: bar, line ! 绘制形状"
rewind(unit=1, iostat=errorLevel)
if ( errorLevel /= 0 ) stop ""
do
read(1, '(A)', iostat=errorLevel) str
if ( errorLevel /= 0 ) exit
write(*, *) Uncomment(str)
end do
contains
function Uncomment(str)
character(len=*), intent(in) :: str
character(len=len(str)) :: Uncomment
integer :: i
integer :: runLevel
runLevel = 0
do i = 1, len(str)
if ( str(i: i) == '!' .and. (runLevel == 0) ) then ! 将感叹号转换为空格
Uncomment(i: i) = ' '
else
Uncomment(i: i) = str(i: i)
end if
if ( str(i: i) == '"' .and. runLevel == 0 ) then ! 判断不转换感叹号的场景
runLevel = 1
elseif ( str(i: i) == '"' .and. runLevel == 1 ) then
runLevel = 0
elseif ( str(i: i) == "'" .and. runLevel == 0 ) then
runLevel = 2
elseif ( str(i: i) == "'" .and. runLevel == 2 ) then
runLevel = 0
end if
end do
end function Uncomment
end subroutine Exercises10_15