Возвращение строки символов неизвестной длины в фортране - PullRequest
3 голосов
/ 29 июня 2010

Извиняюсь за довольно простой вопрос, я просто не могу найти ЛЮБЫХ хороших документов.

Я пытаюсь написать функцию, которая читает из модуля, обрезает вывод и добавляет нольтерминатор, что-то вроде:

character(*) function readCString()
  character*512 str
  read(1, *) str
  readCString = TRIM(str)//char(0)
  return
end function readCString

Тем не менее, я ЗНАЮ, что это не работает, но все же компилируется.Ошибки сегментации не были моим другом в последнее время.Без «символа (*)» перед ключевым словом функции оно не скомпилируется, а при любом значении вместо звезды оно также разрывается, скорее всего потому, что:

TRIM(str)//char(0)

не совпадает с длинойномер я поставил вместо звезды.Я очень плохо знаком с фортраном, но пытаюсь связать некоторый код на фортране с C (отсюда и нулевой терминатор).

Спасибо за любую помощь.

1 Ответ

7 голосов
/ 29 июня 2010
Символ

(звездочка) не является хорошей идеей для использования в качестве функции возврата.символ (звезда) не является строкой длины динамической переменной - это означает получение длины от вызывающей стороны.Поэтому я предлагаю либо использовать строку фиксированной длины в качестве возвращаемой функции, либо использовать символ (*) в качестве аргумента подпрограммы - но в этом случае вызывающая сторона должна заранее зарезервировать память, что просто приводит к фиксации длины для вызывающей стороны.Если вы действительно не знаете максимальную длину и должны иметь строку динамически изменяемой длины, есть способ сделать это.Есть строковый модуль переменной длины.В Fortran 2003 есть выделяемые скейлеры, хотя это не так широко распространено.Вы можете использовать массив из отдельных символов - выделяемые массивы существуют уже давно.

Вот метод, который работает как Fortran:

module test_func_mod
contains
function readCString()
  use iso_c_binding
  character (kind=c_char, len=512)  :: readCString
  character (kind=c_char, len=511) :: str
  read(1, *) str
  readCString = TRIM(str) // C_NULL_CHAR
  return
end function readCString

end module test_func_mod

program test

use test_func_mod

open (unit=1, file="temp.txt")
write (*, *) readCString()

end program test

Если вы хотите связать Fortran и C, я рекомендую использовать новую привязку ISO C.Он предоставляет стандартный и, следовательно, переносимый метод взаимодействия между Fortran и C или любым языком, использующим соглашения о передаче языка C.Это проще в использовании и с меньшей вероятностью взломать, чем взломы, которые должны были быть использованы в прошлом.Хотя он официально является частью Fortran 2003, он уже поддерживается многочисленными компиляторами.Раньше строки были особенно сложными, некоторые компиляторы имели скрытые аргументы длины и т. Д. Привязка ISO C делает все это прозрачным для программиста.Я помню, как приводил пример кода для аналогичного вопроса (Fortran, C и строки) в stackoverflow, но я не могу найти вопрос.

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