Создание перегруженной функции для использования в журнале сообщений

Я пытаюсь создать перегруженную функцию num2str(x), которая будет принимать целые или вещественные значения в качестве входных данных и возвращать строковое значение. Моя цель сделать это - использовать его при записи файла журнала.

Основываясь на предложениях, данных в моем предыдущем сообщении (создание файла журнала), я создали подпрограмму message(msglevel, string), которую я использую для записи файла журнала. Теперь я могу только отправить строку этой функции, и я пытаюсь упростить создание строки с помощью num2str(x).

Может ли кто-нибудь объяснить мне, где я должен разместить этот код (в подпрограмме, в модуле), чтобы я мог получить к нему доступ отовсюду. Я видел пример этого, но он использует его в основная программа, которую я не могу сделать.

Пожалуйста, дайте мне знать, верен ли этот подход. Я также хотел бы знать, могу ли я изменить num2str(x), чтобы возвращать строку для переменных массива.

!GLOBAL FUNCTIONS
interface num2str
    function num2str_int(number)
        integer,intent(in)::number
        character(len=*)::num2str_int
    end function
    character function num2str_real(number)
        real::number
        character(len=*)::num2str_real
    end function
end interface 
function num2str_int(number)
    implicit none
    integer,intent(in)::number
    character(len=*)::num2str_int
    write(num2str_int,'(I)')number
    return
end function
character function num2str_real(number)
    implicit none
    real,intent(in)::number
    character(len=*)::num2str_real
    write(num2str_real,'(F6.4)')number
    return
end function

person Amitava    schedule 01.11.2013    source источник
comment
Вы пытались определить его в модуле и использовать оттуда, и если да, то в чем проблема?   -  person milancurcic    schedule 02.11.2013


Ответы (2)


Я бы определенно пошел на модуль:

module strings

  ! GLOBAL FUNCTIONS
  public :: num2str

  ! Everything else is private
  private

  interface num2str
    module procedure num2str_int
    module procedure num2str_real
  end interface 

contains

  function num2str_int(number)
      implicit none
      integer,intent(in) :: number
      character(len=6)   :: num2str_int
      character(len=6)   :: tmp

      write(tmp,'(I6)')number
      num2str_int = tmp
  end function

  function num2str_real(number)
      implicit none
      real,intent(in)    :: number
      character(len=6)   :: num2str_real
      character(len=6)   :: tmp

      write(tmp,'(F6.4)')number
      num2str_real = tmp
  end function
end module

program test_strings
  use strings

  write(*,*) num2str(1)//' '//num2str(1.23)  
end program
person Alexander Vogt    schedule 01.11.2013
comment
Спасибо за объяснение. Я попытался запустить приведенный выше код, но получил сообщение об ошибке: Error 1 error #5082: Syntax error, found '::' when expecting one of: <IDENTIFIER> в расположении module procedure :: num2str_int. Не знаю, что случилось. - person Amitava; 02.11.2013
comment
А, я наткнулся на это однажды... Просто уберите двойные двоеточия: module procedure num2str_int и module procedure num2str_real. Согласно стандарту Fortran 2008 (глава 12.4.3.2) они необязательны, но у ifort, похоже, с ними проблемы... - person Alexander Vogt; 02.11.2013
comment
Я получаю странную ошибку. Я читаю значение плотности и печатаю его, используя num2str(). По какой-то причине write(tmp,'(F6.4)')number не записывает значение, хранящееся в номере, во tmp. См. мой код и сообщение об ошибке ниже: CODE: function num2str_real(number) implicit none real,intent(in)::number character(len=10):: tmp character(len=10)::num2str_real write(tmp,'(F6.4)')number write(,) "number = ",number write(,) "tmp = ", tmp num2str_real=adjustl(trim(tmp)) return end function RUN: number = 1025.000 tmp = ****** DENSITY = ****** - person Amitava; 02.11.2013
comment
Это связано с переполнением спецификатора формата: F6.4 должен содержать ваш номер. Вам нужно расширить спецификатор (и длину строки). - person Alexander Vogt; 02.11.2013
comment
Спасибо. Это исправило некоторые мои ошибки. Я улучшаю num2str() для отображения массивов, но мой код для отображения массивов не показывает никакого вывода. Не могли бы вы взглянуть. function num2str_array(number,col) implicit none integer::i,col real, dimension(col)::number character(len=32):: tmp character(len=33*col)::num2str_array num2str_array ='' do i=1,col Write (tmp,'(E)') number (I) num2str_array = num2str_array // adjustl(trim(tmp))//"," write(*,*) "num2str_array = ",num2str_array end do return end function - person Amitava; 04.11.2013

Спасибо за вашу помощь. Вот код, который я написал, который должен работать аналогично num2str() в MATLAB. Он также имеет дополнительные функции для отображения массивов и матриц.

module module_common_functions
 !GLOBAL FUNCTIONS
  public :: num2str

  interface num2str
      module procedure num2str_int
      module procedure num2str_real
      module procedure num2str_array
      module procedure num2str_matrix
  end interface

contains

function num2str_int(number)
    implicit none
    integer,intent(in)::number
    character(len=10)::num2str_int
    character(len=10):: tmp
    write(tmp,'(I6)')number
    num2str_int=trim(adjustl(tmp))
    return
end function

function num2str_real(number)
    implicit none
    real,intent(in)::number
    character(len=32):: tmp
    ! Deferred length allocatable character result.
    character(len=:), allocatable ::num2str_real
    ! Format specifier changed to use full length.
    write(tmp,'(F32.4)')number
    ! Reallocation on assignment means length of result will 
    ! be set to match length of right hand side expression.
    ! Note ordering of trim and adjustl.
    num2str_real=trim(adjustl(tmp))
end function

function num2str_array(number,col)
    implicit none
    integer::i,col
    real, dimension(col)::number
    character(len=32):: tmp
    character(len=33*col)::num2str_array
    num2str_array =''
    do i=1,col
        write(tmp,'(F12.4)') number(i)
        num2str_array = trim(num2str_array)//adjustl(trim(tmp))//','
    end do
    return
end function 

function num2str_matrix(number,row,col)
    implicit none
    integer::i,j,row,col
    real,dimension(row,col)::number
     character(len=32):: tmp
    character(len=33*row*col)::num2str_matrix
    num2str_matrix=''

    do i=1,row
        do j=1,col
            write(tmp,'(F12.4)') number(i,j)
            num2str_matrix= trim(num2str_matrix)//adjustl(trim(tmp))//','
        end do
    end do
    return
end function


end module
person Community    schedule 04.11.2013
comment
Нужна помощь. В настоящее время опубликованная программа num2str(x) возвращает необрезанную строку. Следовательно, мне нужно использовать trim(num2str(x)). Есть ли способ исправить это? - person Amitava; 05.11.2013
comment
Два варианта: а) определить и указать точную длину результата в части спецификации самой функции, чтобы не было пробелов в конце, или б) использовать выделяемый символ отложенной длины (добавлен в язык в стандарте Fortran 2003) и сделать обрезку внутри функции. - person IanH; 05.11.2013
comment
Не могли бы вы привести пример варианта (b), который вы упомянули. Я не думаю, что вариант (a) подходит для моего случая. - person Amitava; 05.11.2013