fronthem
fronthem

Reputation: 4139

Removing whitespace in string

I have the following code:

  program main
     character (len=15) :: abc = "te st tex  t"
     print *, trim(abc)      
  end program main

Which outputs:

 te st tex  t

I excepted all the whitespace to be removed but it wasn't. How can I remove all the whitespace from the string?

Upvotes: 5

Views: 23546

Answers (6)

LATTE LAB
LATTE LAB

Reputation: 1

Here is some 30+ year old f77 code that does the trick. Been using it since grad school. Its origins are lost in the mists of time. Possibly written by Michael Mclennan, but really do not know.

c --------------------------------------------------------------------
c   NOSPACE (string)
c
c     This subroutine removes spaces from a character string.
c
c   INPUTS:
c        string...initial character string
c
c   OUTPUTS:
c        string...final character string with all spaces removed
c --------------------------------------------------------------------`
c
      subroutine nospace(string)
c
c     external strlen
      integer strlen
c
      character*(*) string
      integer i, j
c
      i = 1
  10  if (i.le.strlen(string)) then
        if (string(i:i).eq.' ') then
          do 20 j=i,len(string)-1
            string(j:j) = string(j+1:j+1)
  20      continue
c
        else
          i = i + 1
        endif
        goto 10
      endif
c
      return
      end
c --------------------------------------------------------------------
c   integer STRLEN (string)
c
c     The function "len" in Fortran returns the declared length
c   of the string--not the actual length of non-blank characters.
c   This function is provided for that purpose.  It returns the
c   position of the last non-blank character.
c
c   INPUTS:
c        string...character string to determine the length of
c
c   OUTPUTS:
c              ...returns the length of "string"
c --------------------------------------------------------------------
c
      integer function strlen(string)
c
      character*(*) string
c
      integer i
c
      i = len(string)
  10  if ((i.ge.1).and.(string(i:i).eq.' ')) then
        i = i - 1
        goto 10
      endif
c
      strlen = i
c
      return
      end
c

Upvotes: 0

Cesar Augusto Perez
Cesar Augusto Perez

Reputation: 1

You can try this:

program test
!erase blank space in a string
!run over every character of the string and just take every non-blank in other variable.

implicit none

character (len=100) str1,str2
integer i

str2=''                          !in this variable will be save non-blank spaces  
str1='   a   b   c  de   '            !Test string with blank spaces

write(*,*)len_trim(str1), str1

do i=1,len(str1)   
   if (str1(i:i).ne.' ')str2=trim(str2)//trim(str1(i:i))   
end do

write(*,*)len_trim(str2), str2

end 

Upvotes: 0

High Performance Mark
High Performance Mark

Reputation: 78364

For those averse to TRANSFER perhaps a nice little recursive function would appeal. As written this depends on Fortran 2003's ability to automatically allocate character scalars, but it shouldn't be too hard to modify if your compiler doesn't support this feature yet.

  RECURSIVE FUNCTION stripper(string,ch) RESULT(stripped)
    CHARACTER(len=*), INTENT(in) :: string
    CHARACTER, INTENT(in) :: ch
    CHARACTER(:), ALLOCATABLE :: stripped

    IF (LEN(string)==1) THEN
       IF (string==ch) THEN 
          stripped = ''
       ELSE
          stripped = string
       END IF
    ELSE
       IF (string(1:1)==ch) THEN
          stripped = stripper(string(2:),ch)
       ELSE
          stripped = string(1:1)//stripper(string(2:),ch)
       END IF
    END IF
  END FUNCTION stripper

Upvotes: 0

Jauch
Jauch

Reputation: 1518

Trim will remove spaces only at the edges, not in the middle (this is common behaviour on almost all languages/libraries). If you want to remove all spaces in the string, you will have to create your own function to do this, iterating through the string.

Ex.:

program Test

implicit none

    ! Variables
    character(len=200) :: string

    ! Body of Test
    string = 'Hello World              7    9'
    print *, string
    call StripSpaces (string)
    print *, string


contains

    subroutine StripSpaces(string)
    character(len=*) :: string
    integer :: stringLen 
    integer :: last, actual

    stringLen = len (string)
    last = 1
    actual = 1

    do while (actual < stringLen)
        if (string(last:last) == ' ') then
            actual = actual + 1
            string(last:last) = string(actual:actual)
            string(actual:actual) = ' '
        else
            last = last + 1
            if (actual < last) &
                actual = last
        endif
    end do

    end subroutine

end program Test

This was tested on intel compiler, not on gfortran, but I think it will work.

Upvotes: 6

High Performance Mark
High Performance Mark

Reputation: 78364

Here's a dirty, shameful way to eliminate the spaces. This is only likely to work if a compiler lays out a length-15 string in the same order and space as it would a 15-element array of characters. While this is likely to be true, and in my recent experience is true, it is not guaranteed to be so by the standard. That aside, this approach may be good enough.

  ! declarations
  CHARACTER (len=15) :: abc = "te st tex  t"
  CHARACTER, DIMENSION(LEN(abc)) :: abc_array
  ! or CHARACTER, DIMENSION(:), ALLOCATABLE :: abc_array if your compiler supports
  ! automatic allocation

  ! transfer the string into an array of characters
  abc_array = TRANSFER(abc,abc_array)

  ! eliminate the spaces, and transfer back to the string
  abc = TRANSFER(PACK(abc_array,abc_array/=' '),abc)

  ! now all the spaces are at the end of abc so the following statement writes the 
  ! string with no spaces
  WRITE(*,*) TRIM(abc)

Use this approach at your own risk.

Upvotes: 1

John Alexiou
John Alexiou

Reputation: 29264

I was able to do this using the variable string library described here ( http://schonfelder.co.uk/is1539-2-99.htm ). The source code link is found in the introduction section of the ISO document.

Here is the code

program Console1 use ISO_VARYING_STRING implicit none

! Body of Console1
character(LEN=50) :: text = 'Hello World John Mary '
character(LEN=50) :: res

  print *, trim(text)
  ! 'Hello World John Mary'
  res = REPLACE(text,' ','', every=.TRUE.)
  print *, trim(res)
  ! 'HelloWorldJohnMary'
end program Console1

Upvotes: 2

Related Questions