Arrays 读取输入,直到值为<;0

Arrays 读取输入,直到值为<;0,arrays,input,fortran,Arrays,Input,Fortran,除了Fortran之外,其他语言都有很多实现,我无法从中采纳 Sample Input: 5 10 15 20 25 0 Output: Array: [5, 10, 15, 20, 25] Sample Input: 5 10 15 20 25 0 Output: Array: [5, 10, 15, 20, 25] 两种类型的输入都应该有效(一行和多行) 所以,我尝试的是隐含的do循环(因为我确切地知道我可以读取多达N个值);但是,如果输入为0或任何其他值,我无法找到停止读取的方法 我

除了Fortran之外,其他语言都有很多实现,我无法从中采纳

Sample Input:
5 10 15 20 25 0
Output:
Array: [5, 10, 15, 20, 25]

Sample Input:
5
10
15
20
25
0
Output:
Array: [5, 10, 15, 20, 25]
两种类型的输入都应该有效(一行和多行)

所以,我尝试的是隐含的do循环(因为我确切地知道我可以读取多达N个值);但是,如果输入为0或任何其他值,我无法找到停止读取的方法


我已经试过了 这段代码显然不能从一行读取值:

do while (.not.input<0)
    read *, input
end do

do while(.not.input此程序接受stdin的输入。您可以在用空格分隔的一行上输入多个整数。该行可以以0结尾,例如10 20 30 0。您还可以每行输入1个整数,最后一行为0。不允许使用空行

   program foo
   character(len=3) :: fmt = '(A)'
   character(len=80) s, t
   integer :: m=0
   integer, allocatable :: n(:)
   allocate(n(0))
   do
   read(*,fmt) s
5  call get_token(s,t)
   if (len_trim(s) == 0 .and. len_trim(t) == 0) goto 30
   read(t,*,err=15) i
   if (i == 0) goto 20
   n = [n,i]
   m = m + 1
   if (len_trim(s) /= 0) goto 5
   end do
15 write(*,fmt) 'conversion issue'
   goto 40
30 write(*,fmt) 'blank line'
   goto 40
20 if (m == 0) then
   write (*,fmt) 'no elements'
   goto 40
   end if
   write(s,'(I0)') m
   s = '(' // trim(s) // '(I0,1X))'
   write(*,s) n
40 if (allocated(n)) deallocate(n)
   contains
   subroutine get_token(str, token)
   character(len=*), intent(inout) :: str
   character(len=*), intent(out) :: token
   j = scan(trim(str), ' ');
   if (j /= 0) then
   token = str(1:j)
   str = adjustl(str(j:len_trim(str)))
   else
   token = trim(str)
   str = ''
   end if
   end subroutine get_token
   end program foo

可能有一两个错误。啊,有一个错误!没有什么比最后一分钟的小改动更像是在混合中使用扳手。

此程序接受stdin的输入。您可以在一行上放置多个整数,以空格分隔。该行可以以0结尾,例如10 20 30 0。您还可以每行输入一个整数,最后一行为0。a不允许使用空行

   program foo
   character(len=3) :: fmt = '(A)'
   character(len=80) s, t
   integer :: m=0
   integer, allocatable :: n(:)
   allocate(n(0))
   do
   read(*,fmt) s
5  call get_token(s,t)
   if (len_trim(s) == 0 .and. len_trim(t) == 0) goto 30
   read(t,*,err=15) i
   if (i == 0) goto 20
   n = [n,i]
   m = m + 1
   if (len_trim(s) /= 0) goto 5
   end do
15 write(*,fmt) 'conversion issue'
   goto 40
30 write(*,fmt) 'blank line'
   goto 40
20 if (m == 0) then
   write (*,fmt) 'no elements'
   goto 40
   end if
   write(s,'(I0)') m
   s = '(' // trim(s) // '(I0,1X))'
   write(*,s) n
40 if (allocated(n)) deallocate(n)
   contains
   subroutine get_token(str, token)
   character(len=*), intent(inout) :: str
   character(len=*), intent(out) :: token
   j = scan(trim(str), ' ');
   if (j /= 0) then
   token = str(1:j)
   str = adjustl(str(j:len_trim(str)))
   else
   token = trim(str)
   str = ''
   end if
   end subroutine get_token
   end program foo

可能有一两个错误。啊,有一个错误!没有什么比最后一分钟的小变化更能改变局面了。

不推进I/O是前进的方向。你知道数字的格式吗?@IanBush,是的,一个整数(0,如果你知道数字的格式的话)(这意味着每个数字和它们之间的空格——你能提供一种Fortran格式来读取一行,比如4个数字吗?)正如我在上面所暗示的,使用非高级I/O是相当容易的。如果不是,那就不是了。你必须一次一个字符地读入,一次一个字符地解析。这是因为Fortran I/O是一种记录库,与其他许多语言的工作方式不同。在大多数情况下,我发现它比将文件视为字节流更强大、更可取,但它是一种新的方式oes使这变得更加困难。@IanBush,问题是程序不涉及任何外部文件。英特尔Fortran编译器文档中有非常详细的说明,但不涉及“键盘键入”不幸的是。输入定义为整数吗?还是使用隐式类型?您是否将其初始化为某个值>=0,这样循环甚至会首先开始?此外,在您的示例中,没有任何输入<0,因此在这种情况下它永远不会停止。不推进I/O是前进的方向。您知道数字的格式吗?@IanBush,是的,一个整数(0如果你知道数字的格式(这意味着每个数字和它们之间的空格-你能提供一个Fortran格式来读取一行,比如4个数字吗?)正如我在上面所暗示的,使用非高级I/O是相当容易的。如果不是,那就不是了。你必须一次一个字符地读入,一次一个字符地解析。这是因为Fortran I/O是一种记录库,与其他许多语言的工作方式不同。在大多数情况下,我发现它比将文件视为字节流更强大、更可取,但它是一种新的方式oes使这变得更加困难。@IanBush,问题是程序不涉及任何外部文件。英特尔Fortran编译器文档中有非常详细的说明,但不涉及“键盘键入”不幸的是,输入被定义为整数吗?或者您使用隐式类型吗?您是否将其初始化为某个值>=0,这样循环甚至会首先启动?此外,在您的示例中,没有任何输入<0,因此在这种情况下它永远不会停止。