2012-05-25 10 views
8

¿Cómo se escribe una función (Intel) F90 que convierte una cadena en minúscula (o, alternativamente, en mayúscula)? Quiero pasar una matriz de caracteres a la función y hacer que devuelva una matriz de caracteres, p.¿Cómo puedo escribir una función to_upper() o to_lower() en F90?

program main 
    implicit none 

    character*32 :: origStr = "Hello, World!" 
    character*32 :: newStr 

    newStr = to_lower(origStr) 
    write (*,*) newStr 

end program main 

tal que este programa genera hello, world!.

He estado comenzando con la subrutina to_lower() que se encuentra en RosettaCode, pero no puedo encontrar la manera de escribirlo como una función.

¡Gracias de antemano!

PS - puntos de bonificación si puede hacerlo con una cadena de longitud no fijada!

Respuesta

6

Como autor original de este código, me complace que sea de alguna ayuda. Solía ​​preguntarme por qué estas funciones no estaban incorporadas en Fortran. Supongo que solo funcionan para un conjunto bastante restringido de letras, es decir, las que se usan en inglés. Si tiene texto en casi cualquier otro idioma europeo, tendrá caracteres con acentos, y luego convertirlos a mayúsculas o minúsculas es mucho más difícil. Por ejemplo, e-grave en francés convertido en mayúscula se muestra generalmente como simplemente E (se pierde el acento grave), pero en e-agudo no lo hace. Los diseñadores de Fortran siempre han intentado proporcionar instalaciones que se adapten a una amplia gama de idiomas, y hacer conversiones de mayúsculas/minúsculas en una forma multilingüe no es para nada fácil. Al menos esa es mi suposición de por qué tienes que hacerlo tú mismo.

+0

Hola Clive, bienvenido a SO. Empecé a aprender Fortran en 2006 de su libro. Solo quería decir gracias. – milancurcic

+0

No he leído su libro, pero le agradezco su útil código y su perspicaz comentario.Recientemente pasé la rutina a otro colega. Voy a tener que agregarle tu nombre. :-) – jvriesem

13

Guau, aunque he buscado durante más de una hora, inmediatamente después de publicar esto, encontré una respuesta here (en "Misceláneas Fortran Sugerencias y consejos").

El código que utiliza es el siguiente (para to_upper):

function to_upper(strIn) result(strOut) 
! Adapted from http://www.star.le.ac.uk/~cgp/fortran.html (25 May 2012) 
! Original author: Clive Page 

    implicit none 

    character(len=*), intent(in) :: strIn 
    character(len=len(strIn)) :: strOut 
    integer :: i,j 

    do i = 1, len(strIn) 
      j = iachar(strIn(i:i)) 
      if (j>= iachar("a") .and. j<=iachar("z")) then 
       strOut(i:i) = achar(iachar(strIn(i:i))-32) 
      else 
       strOut(i:i) = strIn(i:i) 
      end if 
    end do 

end function to_upper 

Espero que esto ayude a alguien!

+3

esto depende de que achar y iachar se basen en la tabla ASCII, que según mi conocimiento no está estandarizada ... (Dicho esto, básicamente hago lo mismo en mi código y nunca me ha sorprendido el compilador por no usar la tabla ASCII ...) – mgilson

+5

según el estándar FORTRAN 90: "Las funciones intrínsecas ACHAR e IACHAR proporcionan conversiones entre estos caracteres y los enteros de la secuencia de clasificación ASCII." [enlace] (http://www.nag.co.uk/sc22wg5/links.html). ICHAR utilizará el conjunto de caracteres nativos del sistema (que no es necesariamente ASCII). – SimpleSimon

6

Aquí hay uno que no se basa en la representación ASCII

Pure Function to_upper (str) Result (string) 

! ============================== 
! Changes a string to upper case 
! ============================== 

    Implicit None 
    Character(*), Intent(In) :: str 
    Character(LEN(str))  :: string 

    Integer :: ic, i 

    Character(26), Parameter :: cap = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 
    Character(26), Parameter :: low = 'abcdefghijklmnopqrstuvwxyz' 

! Capitalize each letter if it is lowecase 
    string = str 
    do i = 1, LEN_TRIM(str) 
     ic = INDEX(low, str(i:i)) 
     if (ic > 0) string(i:i) = cap(ic:ic) 
    end do 

End Function to_upper 

Usted puede cambiar fácilmente a este to_lower cambiando las cuerdas graves y la tapa en el bucle.

+0

No veo la razón por la cual debería ser más portátil. Las funciones de conversión ASCII son estándar Fortran 90 y, por lo tanto, funcionan también en computadoras con diferentes secuencias de clasificación, ya sea EBCDIC o cualquier otra. Y debido a que su programa también usa otras características de Fortran 90, requiere el compilador Fortran 90 de la misma manera, como lo hace el programa que usa 'achar' .. –

+0

Lo suficiente. Eliminaré la declaración portátil. Personalmente creo que este método es más fácil de entender a primera vista que la versión ASCII ya que no se basa en el conocimiento de la representación ASCII, pero eso es solo una opinión :) – SethMMorton

Cuestiones relacionadas