Как унифицированно читать действительные и комплексные числа в Фортране?

Предположим, у меня есть файл данных (fort.100), содержащий такие данные, как

2.34,          4.5
(23.1,0.3),    4.5
(3.1,0.3),    (3.2,1.0)
2.4,          (32.2,12.0)

как прочитать эти смешанные реальные и комплексные значения в комплексные переменные? Другими словами, следующий простой способ не работает в gfortran.

program readmixnum
implicit none
integer::i
complex::cdat(4,2)
do i=1, 4
read(100,*) cdat(i,1:2)
write(*,*) cdat(i,1:2)
end do
end program

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


person Orders    schedule 12.11.2019    source источник
comment
Какова была ваша попытка? Вы получили какие-либо ошибки? В какой тип кода вам нужно включить это? Какие у вас структуры данных? Вы пробовали написать свой собственный синтаксический анализ, или вы использовали форматирование Fortran, или пробовали читать только в формате списка?   -  person Vladimir F    schedule 12.11.2019
comment
Выясните, каковы ваши спецификации, а затем закодируйте их. например: Отбросить пробелы и запятые, чтобы найти следующую запись. Если запись начинается со скобки, читайте сложное, иначе читайте реальное. И так далее.   -  person L. Scott Johnson    schedule 12.11.2019
comment
Вы понимаете, что вы задали размер cdat с 3 строками, но пытались прочитать 4? Если я это исправлю, код будет работать правильно.   -  person Steve Lionel    schedule 12.11.2019
comment
Однако после изменения он не работает корректно в gfortran. Но сообщение об ошибке с другой информацией должно быть частью вопроса. не работает, не говорит ничего полезного и не должно появляться в хороших вопросах.   -  person Vladimir F    schedule 12.11.2019
comment
Это очень плохо спроектированный файл для чтения, если это вообще возможно, его намного проще анализировать при чтении, настолько просто, что вы можете без проблем использовать направленный на список ввод.   -  person High Performance Mark    schedule 12.11.2019


Ответы (1)


Пожалуйста, попробуйте это как простое решение для вашей проблемы:

program readmixnum
implicit none
integer::i,st
character*256::line
real::rdat(4,2)
complex::cdat(4,2)
do i=1, 4
  read(100,'(A)',iostat=st) line
  read(line,*,iostat=st) rdat(i,:)
  cdat(i,:) = rdat(i,:)
  if (st /= 0) then
    read(line,*,iostat=st) rdat(i,1), cdat(i,2)
    cdat(i,1) = rdat(i,1)
    if (st /= 0) then
      read(line,*,iostat=st) cdat(i,1), rdat(i,2)
      cdat(i,2) = rdat(i,2)
      if (st /= 0) then
        read(line,*,iostat=st) cdat(i,:)
      endif
    endif
  endif
  write(*,*) cdat(i,1:2)
end do
end program

Ему нужна одна реальная матрица rdat того же ранга, что и ваша сложная cdat. Одна строка входного файла fort.100 сохраняется в переменной line. Это предотвращает оператор backspace во время проверки формата числа.

Проверки формата числа выполняются с помощью параметра iostat. Если это значение равно 0, то чтение прошло успешно и числовой формат правильный. Задача состоит в том, чтобы попробовать все возможные комбинации.

Результат:

 (  2.33999991    ,  0.00000000    ) (  4.50000000    ,  0.00000000    )
 (  23.1000004    , 0.300000012    ) (  4.50000000    ,  0.00000000    )
 (  3.09999990    , 0.300000012    ) (  3.20000005    ,  1.00000000    )
 (  2.40000010    ,  0.00000000    ) (  32.2000008    ,  12.0000000    )

для компиляции с gfortran версии 6.3.0 на машине с Linux.

Надеюсь, поможет.

person CKE    schedule 24.11.2019