чтение данных из txt файла в фортране - PullRequest
5 голосов
/ 12 января 2012

Я пишу программу на Фортране, которая читает данные из текстового файла и записывает их в консоль. файл данных выглядит примерно так

1234567890123456 123456.789 987654.321 673647.890 654356.890
6172876534567890 768909.098 234543.890 654321.908 987890.090

У меня есть следующие строки кода FORTRAN, который читает данные и просто записывает их в консоль

 OPEN(1,FILE='data.txt')
    READ(1,'(I16,3F9.3)') A ,B, C, D
    WRITE (*, '(I16,3F9.3)') A,B,C,D
   CLOSE(1)

Вместо отображения одинаковых значений в текстовом файле, следующий вывод

1234567890123456*********89987.656    0.322
6172876534567890*********98234.547    0.891

Не могли бы вы помочь мне с этим.

Большое спасибо

Ответы [ 6 ]

9 голосов
/ 12 января 2012

Управляемый списком ввод-вывод (т. Е. *) Проще, особенно при вводе.Тем не менее, бывают моменты, когда нужно использовать полный контроль ввода-вывода, так что это стоит понять.При вводе элементы данных и дескрипторы должны располагаться по столбцам.Для ввода в Fw.d значение d не имеет значения, если в элементе данных есть десятичная точка.Поля должны быть достаточно широкими как на входе, так и на выходе.Должно быть достаточно дескрипторов, типов которых соответствуют переменным и элементам данных.Сравните с этим примером программы:

program test_read

   implicit none
   integer, parameter :: VLI_K = selected_int_kind (18)
   integer, parameter :: DR_K = selected_real_kind (14)

   integer (VLI_K) :: i
   real (DR_K) :: a, b, c, d

   open (unit=15, file="data.txt", status='old',    &
             access='sequential', form='formatted', action='read' )

   read (15, 110)  i, a, b, c, d
   110 format (I16, 4(1X, F10.0) )
   write (*, 120) i, a, b, c, d
   120 format ( I18, 4 (2X, F12.3) )

   read (15, *) i, a, b, c, d
   write (*, 120) i, a, b, c, d

end program test_read
3 голосов
/ 18 февраля 2014

Мне было труднее всего когда-либо пытаться использовать чтение, но наконец ... Если вы хотите прочитать матрицу, хранящуюся в файле .txt, используйте это:

program FILEREADER

   real, dimension(:,:), allocatable :: x
   integer :: n,m

   open (unit=99, file='array.txt', status='old', action='read')
   read(99, *), n
   read(99, *), m
   allocate(x(n,m))

   do I=1,n,1
      read(99,*) x(I,:)
      write(*,*) x(I,:)
   enddo

end

И, например, файл «array.txt» должен быть таким (и помещаться в ту же самую папку основного файла):

4
3
0.0 1.0 2.0
3.0 4.0 5.0
6.0 7.0 8.0
9.0 10.0 11.0

Надеюсь, что это работает для всех там

2 голосов
/ 19 июля 2012

Я использовал фиксированный формат, потому что редактирование и проверка входных файлов с фиксированной структурой столбцов проще, чем у зигзагообразных данных.Моя проблема заключалась в том, как процедуры чтения с Фортрана во время выполнения интерпретируют наличие и отсутствие десятичных точек.Я не уверен, что мое решение было лучшим, но я читаю строки данных как символьные массивы, разделяю их на поля длиной 12 символов, затем читаю поля с помощью операторов read(*).

1 голос
/ 22 ноября 2016

Небольшая модификация ответа @ Andrés Argüello Guillén .

В отличие от большинства других решений, мой код не заставляет вас заранее указывать количество строк и столбцов.

CHARACTER(128) :: buffer

integer strlen, rows, cols
real, dimension(:,:), allocatable :: x

OPEN (1, file = 'matrix.txt', status='old', action='read')

!Count the number of columns

read(1,'(a)') buffer !read first line WITH SPACES INCLUDED
REWIND(1) !Get back to the file beginning

strlen = len(buffer) !Find the REAL length of a string read
do while (buffer(strlen:strlen) == ' ') 
  strlen = strlen - 1 
enddo

cols=0 !Count the number of spaces in the first line
do i=0,strlen
  if (buffer(i:i) == ' ') then
    cols=cols+1
  endif
enddo

cols = cols+1

!Count the number of rows

rows = 0 !Count the number of lines in a file
DO
  READ(1,*,iostat=io)
  IF (io/=0) EXIT
  rows = rows + 1
END DO

REWIND(1)

print*, 'Number of rows:', rows
print*, 'Number of columns:', cols

allocate(x(rows,cols))

do I=1,rows,1
  read(1,*) x(I,:)
  write(*,*) x(I,:)
enddo

CLOSE (1)

matrix.txt

0.0 1.0 2.0
3.0 4.0 5.0
6.0 7.0 8.0
1 голос
/ 18 апреля 2016

Причина в том, что вы указываете ширину, которая слишком мала для действительных чисел.Обычно, когда ширина не подходит, fortran отображает звездочки, что происходит в вашем случае.

У вас есть 9 цифр, но вам понадобится как минимум 10, поскольку запятая также занимает столбец.Поэтому замена 3F9.3 на 3F10.3 должна помочь.

0 голосов
/ 12 января 2012

Обычно лучше читать данные в нефиксированном формате. И оставить несколько начальных пробелов, чтобы цифры могли помещаться при их записи.

integer(8) :: i
real(4) :: x, y, z
open(unit=1, file='data.txt')
read(1,*)i, x, y, z
write(*,'(i16, 3f11.3)')i, x, y, z
end
...