Я хотел бы прочитать файл данных с программой Fortran, где каждая строка представляет собой список целых чисел.Чтение файла списков целых чисел в Fortran
Каждая строка имеет переменное число целых чисел, разделенных данным символом (пробел, запятая ...).
Пример ввода:
1,7,3,2
2,8
12,44,13,11
У меня есть решение разделить строки, которые я нахожу довольно запутанным:
module split
implicit none
contains
function string_to_integers(str, sep) result(a)
integer, allocatable :: a(:)
integer :: i, j, k, n, m, p, r
character(*) :: str
character :: sep, c
character(:), allocatable :: tmp
!First pass: find number of items (m), and maximum length of an item (r)
n = len_trim(str)
m = 1
j = 0
r = 0
do i = 1, n
if(str(i:i) == sep) then
m = m + 1
r = max(r, j)
j = 0
else
j = j + 1
end if
end do
r = max(r, j)
allocate(a(m))
allocate(character(r) :: tmp)
!Second pass: copy each item into temporary string (tmp),
!read an integer from tmp, and write this integer in the output array (a)
tmp(1:r) = " "
j = 0
k = 0
do i = 1, n
c = str(i:i)
if(c == sep) then
k = k + 1
read(tmp, *) p
a(k) = p
tmp(1:r) = " "
j = 0
else
j = j + 1
tmp(j:j) = c
end if
end do
k = k + 1
read(tmp, *) p
a(k) = p
deallocate(tmp)
end function
end module
Мой вопрос:
Есть более простой способ сделать это в Fortran? Я имею в виду, прочитав список значений, где количество прочитанных значений неизвестно. Вышеприведенный код выглядит неудобно, и файловый ввод-вывод не выглядит легким в Fortran.
Кроме того, основная программа должна читать строки с неизвестной и неограниченной длиной. Я могу читать строки, если предположить, что они имеют одинаковую длину (см. Ниже), но я не знаю, как читать неограниченные строки. Полагаю, для этого нужны потоковые функции Fortran 2003, но я не знаю, как это написать.
Вот текущая программа:
program read_data
use split
implicit none
integer :: q
integer, allocatable :: a(:)
character(80) :: line
open(unit=10, file="input.txt", action="read", status="old", form="formatted")
do
read(10, "(A80)", iostat=q) line
if(q /= 0) exit
if(line(1:1) /= "#") then
a = string_to_integers(line, ",")
print *, ubound(a), a
end if
end do
close(10)
end program
Комментарий к вопросу: как правило, я хотел бы сделать это в Python, например, преобразование строки будет столь же просто, как a = [int(x) for x in line.split(",")]
и чтение файла также почти тривиальная задача. И я бы сделал «реальный» компьютерный материал с помощью Fortran DLL. Тем не менее, я бы хотел улучшить свои навыки Fortran для ввода/вывода файлов.
Спасибо! Я не знал этого использования запятой для ввода массива. Что касается претензий к Fortran и обработке строк, возможно, я склонен, так как я изучил Python задолго до того, как узнал Fortran: для строк и ввода-вывода это было шоком :) Из-за этого я удалил свой комментарий, поскольку он, вероятно, несправедлив. Тем не менее, у меня все еще создается впечатление, что в Fortran у вас есть что делать самостоятельно, а синтаксис - не очень дружелюбный. –