如何判断用户输入的数据类型?
How to determine data type entered by user?
我正在编写一个模拟 ATM 机工作的程序。
基本上,如果输入无效字符,我想显示一条错误消息。例如:
'Please enter your name...'
[here user enters a random **digit**, which is not a character]
[here I want the program to **determine** whether the input type is
*character* or *integer* and then decide what to do next :
show an error or continue running]
我只是想知道有没有可能做到这一点?
有两件事。更容易看到是否有人输入了数字。 Read 将尝试将输入的值放入提供的变量中,如果无法做到这一点,它将 iostat
参数设置为正数:
program determine
implicit none
integer :: iNumber
integer :: io_stat
do
print *, "Please enter a number"
read(*, *, iostat=io_stat) iNumber
if (io_stat == 0) exit
print *, "This isn't a number, try again!"
end do
print *, "You entered a number ", iNumber
end program determine
当然,另一种方法并不那么容易。 "Hello" 永远不是整数,但“12”肯定是字符串。所以在那种情况下,您必须直接验证字符串。一个简单、快捷的解决方案是这样的:
program determine
implicit none
character(len=50) :: cName
do
print *, "Please enter a name: (A-Za-z)"
read(*, '(A50)') cName
if (valid_input(cName)) exit
print *, "No valid input! Try again!"
end do
print *, "You entered the name " // trim(cName)
contains
function valid_input(cName)
implicit none
character(len=*), intent(in) :: cName
logical :: valid_input
integer :: i
valid_input = .false.
if (len_trim(cName) == 0) return
do i = 1, len_trim(cName)
select case(ichar(cName(i:i)))
case(ichar('A'):ichar('Z'))
continue
case(ichar('a'):ichar('z'))
continue
case default
return
end select
end do
valid_input = .true.
end function valid_input
end program determine
更新: 正如@francescalus 在此答案的评论中指出的,您还可以使用 VERIFY
关键字来检查字符串中的不合格字符.当然,这意味着您必须将每个符合要求的字母输入到 SET
字符串中,但它仍然比我的 valid_input
方法短:
function valid_input(cName)
implicit none
character(len=*), intent(in) :: cName
logical :: valid_input
valid_input = &
( ( len_trim(cName) > 0 ) .and. &
( verify(trim(cName), &
'ABCDEFGHIJKLMNOPQRSTUVWXYZ' // &
'abcdefghijklmnopqrstuvwxyz' &
) == 0 &
) &
)
end function valid_input
现在当然这不会验证其中包含空格或其他非标准字母的名称。如果您需要更复杂的东西,您几乎就要实现正则表达式了。有关示例,请参阅 here。
我正在编写一个模拟 ATM 机工作的程序。 基本上,如果输入无效字符,我想显示一条错误消息。例如:
'Please enter your name...'
[here user enters a random **digit**, which is not a character]
[here I want the program to **determine** whether the input type is
*character* or *integer* and then decide what to do next :
show an error or continue running]
我只是想知道有没有可能做到这一点?
有两件事。更容易看到是否有人输入了数字。 Read 将尝试将输入的值放入提供的变量中,如果无法做到这一点,它将 iostat
参数设置为正数:
program determine
implicit none
integer :: iNumber
integer :: io_stat
do
print *, "Please enter a number"
read(*, *, iostat=io_stat) iNumber
if (io_stat == 0) exit
print *, "This isn't a number, try again!"
end do
print *, "You entered a number ", iNumber
end program determine
当然,另一种方法并不那么容易。 "Hello" 永远不是整数,但“12”肯定是字符串。所以在那种情况下,您必须直接验证字符串。一个简单、快捷的解决方案是这样的:
program determine
implicit none
character(len=50) :: cName
do
print *, "Please enter a name: (A-Za-z)"
read(*, '(A50)') cName
if (valid_input(cName)) exit
print *, "No valid input! Try again!"
end do
print *, "You entered the name " // trim(cName)
contains
function valid_input(cName)
implicit none
character(len=*), intent(in) :: cName
logical :: valid_input
integer :: i
valid_input = .false.
if (len_trim(cName) == 0) return
do i = 1, len_trim(cName)
select case(ichar(cName(i:i)))
case(ichar('A'):ichar('Z'))
continue
case(ichar('a'):ichar('z'))
continue
case default
return
end select
end do
valid_input = .true.
end function valid_input
end program determine
更新: 正如@francescalus 在此答案的评论中指出的,您还可以使用 VERIFY
关键字来检查字符串中的不合格字符.当然,这意味着您必须将每个符合要求的字母输入到 SET
字符串中,但它仍然比我的 valid_input
方法短:
function valid_input(cName)
implicit none
character(len=*), intent(in) :: cName
logical :: valid_input
valid_input = &
( ( len_trim(cName) > 0 ) .and. &
( verify(trim(cName), &
'ABCDEFGHIJKLMNOPQRSTUVWXYZ' // &
'abcdefghijklmnopqrstuvwxyz' &
) == 0 &
) &
)
end function valid_input
现在当然这不会验证其中包含空格或其他非标准字母的名称。如果您需要更复杂的东西,您几乎就要实现正则表达式了。有关示例,请参阅 here。