Форматированные чтения и подразумеваемое выполнение

#fortran

#fortran

Вопрос:

В Fortran есть возможность использовать подразумеваемые циклы. Они обычно используются для печати и имеют следующую структуру.

 write(*,'(5I6)') (i,i=1,20)

! output 
 1     2     3     4     5
 6     7     8     9    10
11    12    13    14    15
16    17    18    19    20
  

Это позволило бы записать 5 целых чисел шириной 6 и, когда это будет сделано, автоматически перейти к следующей строке. Поэтому это весьма полезно для форматирования.

Вопрос в том, можно ли это сделать наоборот

 read(*,'(5I6)') (a(i),i=1,20)
  

Это, конечно, не сработало бы, как написано, потому что в строке всего 5 элементов. Тем не менее я хотел бы спросить, как перейти к следующей строке в автоматическом режиме. В настоящее время я подсчитываю количество записей, и как только будет достигнуто 5, я перехожу к следующей строке. Другим вариантом было бы прочитать файл в двоичном scratch-файле, где не существует «новых» строк. Для меня это не сработало бы аккуратно, потому что я использую поиск по ключевым словам с index() помощью функции.

Комментарии:

1. Что вы подразумеваете под «Это, конечно, не сработает»? Основная проблема заключается в том, что у вас нет входной переменной для чтения, но почему, по-вашему, такой ввод не выполняется чаще?

2. Я был слишком быстр при вводе, конечно, я должен читать в массиве. Я отредактировал вопрос. Спасибо, что указали на это.

3. Или, если a имеет 20 элементов, read(*,*) a с высокой вероятностью считывает 20 элементов из файла. В простых случаях не так много можно получить ни от явных форматов ввода, ни от подразумеваемых циклов выполнения.

4. Это работает великолепно, проблема заключалась в том, что значения выглядели так 1.711111-01-1.411111-01 : нет пробела между отрицательным числом и числом перед ним, также нет E для экспоненциальной записи. Это привело к чтению в файл. Я должен выяснить, как это исправить.

5. проблема заключалась в том, что значения выглядели следующим образом 1.711111-01-1.411111-01 Я думаю, вы неправильно поняли вопрос, который совершенно явно касается чтения и записи целых чисел.

Ответ №1:

Я бы сделал это так, если вам действительно нужен формат по какой-то причине

 do i = 1, n, 5
  read(*,'(5I6)') a(i:i 4)
end do
  

в противном случае формат, ориентированный на список, будет работать хорошо, как предлагает High Performance Mark.

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

Я мог бы даже представить однострочник с включением дескриптора формата / , но зачем беспокоиться?

(слишком долго для комментария)

Комментарии:

1. На самом деле проблема была связана с неправильным форматом входных данных. Экспоненциальные числа записываются в этой форме 1.711111-01-1.411111-01 , и, поскольку они, по-видимому, объединены, чтение завершилось неудачно

2. На самом деле, другой ответ лучше.

Ответ №2:

Возврат формата здесь является ключевым термином. Это относится как к выходу, так и к вводу.

Прежде чем идти дальше, подразумеваемое выполнение в значительной степени не имеет значения, поэтому я буду придерживаться операторов передачи данных с целыми массивами. Это верно для первого вывода, где это также может быть массив со значениями от 1 до 20, а не подразумеваемое выполнение (попробуйте!). Итак,

 read (*,fmt) a
  

точно так же, как

 read (*,fmt) (a(i),i=1,20)
  

когда a имеет эти границы.

Для вывода переход «автоматически к следующей строке» является частью обработки вывода с возвратом формата. Как только элементы формата будут исчерпаны и останется еще больше элементов для записи, мы возвращаемся к началу формата. Мы также переходим к началу следующей записи. В данном случае это начало новой строки. Что дает результат

  1     2     3     4     5
 6     7     8     9    10
11    12    13    14    15
16    17    18    19    20
  

После каждого пятого элемента из двадцати мы начинаем новую строку.

Возврат формата при чтении тот же. Учитывая

 read(*,'(5I6)') a
  

пять элементов a передаются в соответствии с 5I6 частью формата. В этот момент список элементов формата исчерпан, и происходит возврат к формату. Возврат к началу формата и переход к следующей записи.

В заключение

 read(*,'(5I6)') a
  

является обратным

 write(*,'(5I6)') a
  

Комментарии:

1. Верно, я не забыл о возврате формата, но я забыл, что конец записи вставляется автоматически.