Массив строк в Фортране 77 - PullRequest
       23

Массив строк в Фортране 77

7 голосов
/ 07 апреля 2009

У меня вопрос о Fortran 77, и я не смог найти решение.

Я пытаюсь сохранить массив строк, определенных следующим образом:

character matname(255)*255

, представляющий собой массив из 255 строк длиной 255.

Позже я читаю список имен из файла и устанавливаю содержимое массива следующим образом:

matname(matcount) = mname

РЕДАКТИРОВАТЬ: На самом деле mname значение жестко закодировано как mname = 'AIR' типа character*255, это параметр функции matadd(), которая выполняет предыдущую строку. Но это только для тестирования, в будущем оно будет прочитано из файла.

Позже я хочу напечатать его:

write(*,*) matname(matidx)

Но кажется, что напечатаны все 255 символов, напечатана назначенная мной строка и много мусора.

  • Итак, это мой вопрос, как я могу узнать длину сохраненной строки?
  • Должен ли я иметь другой массив со всеми длинами?
  • А как узнать длину прочитанной строки?

Спасибо.

Ответы [ 4 ]

5 голосов
/ 07 апреля 2009

Вы можете использовать эту функцию, чтобы получить длину (без пустого хвоста)

integer function strlen(st)
      integer       i
      character     st*(*)
      i = len(st)
      do while (st(i:i) .eq. ' ')
        i = i - 1
      enddo
      strlen = i
      return
      end

Получил отсюда: http://www.ibiblio.org/pub/languages/fortran/ch2-13.html

PS: Когда вы говорите: matname (matidx), он получает всю строку (256) символов ... так что это ваша строка плюс пробелы или мусор

4 голосов
/ 07 апреля 2009

Функция, которую опубликовал Timotei, даст вам длину строки, пока интересующая ее часть содержит только пробелы, которые, если вы присваиваете значения в программе, должны быть истинными, как предполагается для FORTRAN. инициализируйте переменные, чтобы они были пустыми и для символов это означает пробел.

Однако, если вы читаете из файла, вы можете выбрать другие управляющие символы в конце строк (особенно символы возврата каретки и / или перевода строки, \ r и / или \ n в зависимости от вашей ОС). Вы также должны выбросить их в функцию, чтобы получить правильную длину строки. В противном случае вы можете получить несколько забавных выражений для печати, так как эти символы также печатаются.

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

  function strlen(st)
  integer           i,strlen
  character         st*(*)
  i = len(st)
  do while ((st(i:i).eq.' ').or.(st(i:i).eq.'\r').or.
 +  (st(i:i).eq.'\n').or.(st(i:i).eq.'\t'))
    i = i - 1
  enddo
  strlen = i
  return
  end

Если в разделе «мусор» есть другие символы, это все равно не будет работать полностью.

Предполагая, что он работает для ваших данных, вы можете затем изменить свой оператор записи следующим образом:

write(*,*) matname(matidx)(1:strlen(matname(matidx)))

и он распечатает только фактическую строку.

Относительно того, следует ли использовать другой массив для хранения длин строки, это зависит от вас. функция strlen () - это O (n), тогда как поиск длины в таблице - это O (1). Если вам часто приходится вычислять длины этих статических строк, это может повысить производительность, вычисляя длину один раз, когда они считываются, сохраняя их в массиве и просматривая их, если они вам нужны. Однако, если вы не заметите замедления, я бы об этом не беспокоился.

1 голос
/ 07 апреля 2009

В зависимости от того, какой компилятор вы используете, вы можете использовать встроенную функцию trim() для удаления любых начальных / конечных пробелов из строки, а затем обработать ее, как обычно, т.е.

character(len=25) :: my_string
my_string = 'AIR'
write (*,*) ':', trim(my_string), ':'

должен напечатать :AIR:.

Edit: Более того, похоже, что есть функция len_trim(), которая возвращает длину строки после ее обрезки.

0 голосов
/ 18 июня 2013

intel и Compaq Visual Fortran имеют встроенную функцию LEN_TRIM (STRING), которая возвращает длину без пробелов и пробелов.

Если вы хотите подавить начальные пробелы или пробелы, используйте «Adjust Left», т.е. ADJUSTF (STRING)

В этих FORTRAN я также отмечаю полезную особенность: если вы передаете строку в функцию или подпрограмму в качестве аргумента, а внутри подпрограммы она объявляется как CHARACTER * (*), тогда использование функции LEN (STRING) в подпрограмме повторяет фактическую длину переданной строки, а не длину строки, как объявлено в вызывающей программе.

Пример: CHARACTER * 1000 STRING

        .
        .

  CALL SUBNAM(STRING(1:72)

  SUBROUTINE SYBNAM(STRING)
  CHARACTER*(*) STRING
  LEN(STRING) will be 72, not 1000
...