2010-06-29 2 views
3

Извинения за довольно простой вопрос, я просто не могу найти ЛЮБОЙ хороший fortran docs.Возвращаемая строка символов неизвестной длины в fortran

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

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

Однако, я знаю, что это еще не работает компилирует. В последнее время недостатки сегментации не были моим другом. Без «характер (*)» до функции ключевого слова он не будет компилировать, и с любым значением вместо звезды также влезает, скорее всего, потому что:

TRIM(str)//char(0) 

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

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

ответ

7

знак (звезда) не рекомендуется использовать как функцию возврата. character (star) не является строкой динамической переменной длины - это означает получение длины от вызывающего. Поэтому я предлагаю использовать строку фиксированной длины в качестве возвращаемой функции или использовать символ (*) в качестве аргумента подпрограммы, но в этом случае вызывающему нужно заранее зарезервировать память, что просто подталкивает фиксацию длины вызывающему. Если вы действительно не знаете максимальную длину и должны иметь динамическую переменную длину, есть способ сделать это. Существует строковый модуль переменной длины. У 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 Binding. Он предоставляет стандартный и, следовательно, переносимый метод взаимодействия с Fortran и C или любым языком, использующим соглашения о передаче C. Его легче использовать и реже ломать, чем хаки, которые нужно было использовать в прошлом. Хотя она официально входит в состав Fortran 2003, она уже поддерживается многочисленными компиляторами. Строки были особенно сложными, некоторые компиляторы имели скрытые аргументы длины и т. Д. Связывание ISO C делает все это прозрачным для программиста. Я помню, как я приводил пример кода для аналогичного вопроса (Fortran, C и строки) в stackoverflow, но я не могу найти вопрос.

Смежные вопросы