String case: Difference between revisions

Content added Content deleted
Line 1,014: Line 1,014:


Note that in EBCDIC the offset is not 32 but 64. Rather than using an undocumented "magic constant" such as 32, one could define <code>PARAMETER (HIC = ICHAR("A") - ICHAR("a"))</code> instead or just place such code in-line and have hope for the compiler. This would also handle the small detail that "A" > "a" in EBCDIC rather than ASCII's "A" < "a". But alas, in EBCDIC the letter codes are ''not'' contiguous (there are many non-letter symbols between "a" and "z" as well as between "A" and "Z"), so the bounds of "A" to "Z" will ''not'' isolate only letters for attack. And it was not just IBM mainframes that used various versions of EBCDIC, so also did Burroughs, among others.
Note that in EBCDIC the offset is not 32 but 64. Rather than using an undocumented "magic constant" such as 32, one could define <code>PARAMETER (HIC = ICHAR("A") - ICHAR("a"))</code> instead or just place such code in-line and have hope for the compiler. This would also handle the small detail that "A" > "a" in EBCDIC rather than ASCII's "A" < "a". But alas, in EBCDIC the letter codes are ''not'' contiguous (there are many non-letter symbols between "a" and "z" as well as between "A" and "Z"), so the bounds of "A" to "Z" will ''not'' isolate only letters for attack. And it was not just IBM mainframes that used various versions of EBCDIC, so also did Burroughs, among others.

Here a complete example, using functions, and as far as I can tell, will work also with EBCDIC:

<lang Fortran>
module uplow
implicit none
character(len=26), parameter, private :: low = "abcdefghijklmnopqrstuvwxyz"
character(len=26), parameter, private :: high = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
contains

function to_upper(s) result(t)
! returns upper case of s
implicit none
character(len=*), intent(in) :: s
character(len=len(s)) :: t

character(len=1), save :: convtable(0:255)
logical, save :: first = .true.
integer :: i

if(first) then
do i=0,255
convtable(i) = char(i)
enddo
do i=1,len(low)
convtable(iachar(low(i:i))) = char(iachar(high(i:i)))
enddo
first = .false.
endif

t = s

do i=1,len_trim(s)
t(i:i) = convtable(iachar(s(i:i)))
enddo

end function to_upper

function to_lower(s) result(t)
! returns lower case of s
implicit none
character(len=*), intent(in) :: s
character(len=len(s)) :: t

character(len=1), save :: convtable(0:255)
logical, save :: first = .true.
integer :: i

if(first) then
do i=0,255
convtable(i) = char(i)
enddo
do i = 1,len(low)
convtable(iachar(high(i:i))) = char(iachar(low(i:i)))
enddo
first = .false.
endif

t = s

do i=1,len_trim(s)
t(i:i) = convtable(iachar(s(i:i)))
enddo

end function to_lower


end module uplow


program doit
use uplow
character(len=40) :: s

s = "abcdxyz ZXYDCBA _!@"
print *,"original: ",'[',s,']'
print *,"to_upper: ",'[',to_upper(s),']'
print *,"to_lower: ",'[',to_lower(s),']'

end program doit
</lang>


=={{header|FreeBASIC}}==
=={{header|FreeBASIC}}==