Фортран читает ввод в динамический массив - PullRequest
0 голосов
/ 16 декабря 2011

Я хотел бы прочитать координаты из входного файла.Пример входного файла будет выглядеть примерно так:

1    0.1542    0.2541    1.2451   N
12   4.5123    2.0014    2.0154   O
43   8.2145    0.2978    4.2165   H

и т.д ... Размер этого файла является переменным.Первый столбец - это число, присвоенное атому, следующие столбцы - его координаты x, y, z, а последний столбец - элементарный символ атома.

Я пробовал что-то вроде:

integer, allocatable :: atnum(:)
double precision, allocatable :: coord(:,:)
character(len=2), allocatable :: element(:)

open(unit=20, file='input', status='old',action='read')

read(20,*,end=200) atnum, coord(:,1:3), element
200 close(20)

Это выдает мне ошибку:

Fortran runtime error: Bad integer for item 2 in list input

Я предполагаю, что программа прочитала первую запись в atnum(1), но затем попытался продолжить чтение во второй записи первого ряда в atnum(2).Как я могу заставить его правильно читать входные данные?

Я также думаю, что может быть проблема с указанием программе прочитать три средних столбца в coord(:,1:3).Вполне вероятно, что он прочитает первые три записи в coord(1,1), coord(2,1), coord(3,1), затем натолкнется на символ в конце строки и снова запутается.Как я могу сказать ему исправить первый индекс строки и прочитать в другое измерение?Или мне придется поменять местами индексы, например coord(1:3,:)?Будет ли это работать?

РЕДАКТИРОВАТЬ: выше сказанное tpg2114, но у меня все еще есть проблема.Я не могу выделить массив, пока не узнаю, сколько наборов координат нужно прочитать, но я знаю только, сколько атомов, пока не достигну конца файла.Программа компилируется нормально, если я не выделяю atnum, coord and element, но возвращает ошибку сегментации, когда я пытаюсь ее запустить.Как я могу заставить его считывать динамические массивы без предварительного их выделения?

Звучит примерно так: Массивы переменного размера в Fortran без Allocate ()

Заранее спасибо.

Ответы [ 2 ]

3 голосов
/ 16 декабря 2011

Шаг 1: Считайте файл, прочитав каждую строку в строку, просто чтобы посчитать строки как «num_lines», используя «iostat» для определения условия конца файла.

Шаг 2:перемотать файл.

Шаг 3: выделить массивы правильной длины "num_lines".

Шаг 4: выполнить "фактическое" чтение файла в массивы, элемент за элементом:

do i=1, num_lines
   read (20, *) atnum(I), coord(I,1:3), elem(I)
end do
3 голосов
/ 16 декабря 2011

Вам нужно перебрать оператор READ.Один READ будет идти только до конца записи, в данном случае строки.Вы узнаете, когда у вас закончились строки, потому что вы поставили аргумент end = 200, поэтому он перейдет к строке 200 (которой, похоже, здесь нет).

Итак, вам нужно убедиться:

A) Ваши массивы достаточно длинные, чтобы содержать файл (вы не показываете выделение для них, я предполагаю, что вы их выделили?)

B) Вы перебираете оператор READ

C) Вы указываете индекс для аргумента atnum и первый аргумент скоординированного и аргумента elem.

Например, если предположить, что объявления одинаковы, а массивы выделены достаточно большими, а I - INTEGER

I = 1
DO 
  read(20,*,end=200) atnum(I), coord(I,1:3), elem(I)
  I = I + 1
END DO 
200 continue

Также рассмотрите возможность удаления части end = 200 и использования вместо нее IOSTATтак как это современно и номера строк устарели.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...