2015-10-03 1 views
0

Я хочу использовать следующую функцию в своем коде. Я хочу, чтобы он взял заданную строку, вырезал все ведущие нули и вернул строку без начальных нулей. Например я даю ему '00023' и он возвращает '23___' (_ пространство) У меня есть эта функция в моем коде:Невозможно скомпилировать функцию, которая возвращает части строки

function cut_zeros(string) 
implicit none 
    character(5) :: cut_zeros, string 
    integer:: string_limit, i 

    string_limit = 5 

    do i= 1, string_limit 
     if (string(i)/='0') then 
      cut_zeros = string(i : string_limit) 
      exit 
     endif 
    enddo 

end function cut_zeros 

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

cut_zeros = string(i : string_limit) 
         1 
Error: Syntax error in argument list at (1) 

У меня также есть другой вопрос? Можно ли сделать предполагаемую длину функции? Так что я могу передать ему строку любой длины? Насколько я понимаю, это невозможно, потому что возвращаемое значение функции нельзя считать длиной, верно?

ответ

4

Сообщение об ошибке на самом деле вводит в заблуждение. Ошибка имеет одну строку выше: для сравнения i-го символа вам нужно использовать string(i:i). Если вы измените эту строку на

if (string(i:i)/='0') then 

код работает как ожидалось.

Для второй части вашего вопроса вы можете использовать строки предполагаемой длины! Вы можете просто установить длину возвращаемого значения для длины входной строки:

function cut_zeros(string) 
implicit none 
    character(*) :: string 
    character(len=len(string)) :: cut_zeros 
    integer:: string_limit, i 

    string_limit = len(string) 

    do i= 1, string_limit 
     if (string(i:i)/='0') then 
      cut_zeros = string(i : string_limit) 
      exit 
     endif 
    enddo 
end function cut_zeros 

Здесь длиной возвратной строки выбирается, что, если не нули не будут удалены, он все еще имеет правильную длину. Обратите внимание, что вам потребуется интерфейс для обработки допустимых аргументов длины.

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

function cut_zeros(string) 
implicit none 
    character(*) :: string 
    character(len=:),allocatable :: cut_zeros 
    integer:: string_limit, i 

    string_limit = len(string) 

    do i= 1, string_limit 
     if (string(i:i)/='0') then 
      allocate(character(len=string_limit-i+1) :: cut_zeros) 
      cut_zeros = string(i : string_limit) 
      exit 
     endif 
    enddo 
end function cut_zeros 
+0

спасибо, это было действительно полезно для меня! Что вы имеете в виду: «Обратите внимание, что вам понадобится интерфейс для обработки допустимых аргументов длины длины».? – Skyy2010

+1

Вам нужно либо указать 'interface' для функции самостоятельно, либо (даже лучше) вы поместите функцию внутри модуля и дайте компилятору выполнить эту работу за вас. –

0

Синтаксис ссылки подстроки требуют разделяющего двоеточия, то есть вы хотите string(i:i) , Если у вас нет этого двоеточия, компилятор считает, что синтаксис является ссылкой на функцию (он знает, что это не ссылка на массив, потому что вы не объявили string как массив).

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

FUNCTION cut_zeros(string) 
    CHARACTER(*), INTENT(IN) :: string 
    ! The length of the function result is the same as the length 
    ! of the argument. 
    CHARACTER(LEN(string)) :: cut_zeros 

Функция с автоматическим результатом требует явного интерфейса в любой области, на которую ссылается. Лучше всего поместить его в модуль и использовать модуль.

+0

Благодарю вас за помощь! Можете ли вы еще раз объяснить, что вы имеете в виду под «Функция с автоматическим результатом требует явного интерфейса в любой области, на которую он ссылается». Я не понимаю, что вы имеете в виду здесь. Что вы подразумеваете под интерфейсом и областью? – Skyy2010

1

Или вы могли бы использовать существующие возможности языка Fortran

CHARACTER(6) :: src = '002305' 
    CHARACTER(LEN(src)) :: dest 
    ... 
    dest = src(SCAN(src,'123456789'):) 
    ! now dest is '2305__' 

это работает только, если первый не-0 символ другая цифра, если у вас есть другие символы, чтобы беспокоиться о расширить набор, используемый во 2-е аргумента SCAN ,

+0

спасибо, не знали об этой функции! – Skyy2010