CHARACTER*1 A, B, C
A = 'k'
B = 'u'
C = 'l'
WRITE(*,*) A, B, C
END
Ovanstående utnyttjar Fortran 77 deklationen CHARACTER*1 A
för att specificiera att variabeln A är en
textsträngsvariabel med längden 1.
I Fortran 95 är motsvarande deklaration i stället
CHARACTER(LEN=1) :: A
En intressant variant är att använda konkatenering (summation) av tecken, vilket sker med symbolen två snedstreck //. Följande modifierade program har därför samma resultat som det föregående.
CHARACTER(LEN=1) :: A, B, C
A = 'k'
B = 'u'
C = 'l'
WRITE(*,*) A // B // C
END
Konkateneringen blir mer värdefull då vi väljer att sätta det nya resultatet
i en längre variabel, vilken jag kallar för textsträng. Andra svenska böcker
föredrar ordet teckensträng.
CHARACTER(LEN=1) :: A, B, C
CHARACTER(LEN=3) :: D
A = 'k'
B = 'u'
C = 'l'
D = A // B // C
WRITE(*,*) D
END
Vi kan nu börja med en verklig textmanipulering, till exempel genom att i stället omforma
textsträngen kul till ull. Vi utgår nu i stället från den direkta tilldelningen
av tre bokstäver till textsträngsvariabeln D, och placerar den andra bokstaven först
och därefter den tredje bokstaven på den andra platsen.
CHARACTER(LEN=3) :: D
D = 'kul'
D(1:1) = D(2:2)
D(2:2) = D(3:3)
WRITE(*,*) D
END
Vi kan även omforma textsträngen kul till ull på ett "tuffare" sätt, genom
att kopiera de båda sista bokstäverna till de båda första positionerna.
Detta förfarande är tillåtet och entydigt även i detta överlappande
fall i Fortran 90, men ej i Fortran 77.
CHARACTER(LEN=3) :: D
D = 'kul'
D(1:2) = D(2:3)
WRITE(*,*) D
END
En annan nyhet är att en tom sträng nu är tillåten, dvs "ingenting" mellan
de båda "blipparna" är tillåtet och tolkas som en tom textsträng, vilket
kan vara bra vid iterativa processer.
Jämförelse sker utnyttjande de gamla symbolerna
.LT. .LE. .EQ. .NE. .GT. .GE.
eller motsvarande nya och mer matematiska
< <= == /= > >=
Notera att eftersom likhetstecknet = användes som tilldelningstecken (motsvarande := i Pascal)
så måste vi välja ett annat tecken för likhet, nämligen
.EQ. eller
= =. Kompilatorer är ofta skrivna så att de påstår att
symbolen .LT. har
använts på fel sätt, även om man i själva verket använt symbolen
<.
Observera att vi även har tillgång till ett antal logiska operatorer, nämligen .NOT. .AND. .OR. samt de mer ovanliga .EQV. och .NEQV. De definieras i nedanstående tabell, men de har tyvärr ingen modernare beteckning än "punktnamnen".
A T T F F
B T F T F
.NOT. A F F T T
A .AND. B T F F F
A .OR. B T T T F
A .EQV. B T F F T
A .NEQV. B F T T F
I Fortran 77 infördes ett alternativ till den maskinberoende sorteringsordning
som erhålles
med jämförelser av typ
IF (CHAR1 .LT. CHAR2 ) THEN
nämligen de fyra logiska funktionerna
LGE, LGT, LLE och LLT, vilka är baserade på
sorteringsordning enligt ASCII och som argument har två textsträngar. Ovanstående
jämförelse skrives då
IF ( LLT(CHAR1, CHAR2) ) THENvarvid en maskinoberoende sortering erhålles.
Fyra andra funktioner i Fortran 77 ger det nummer som svarar mot ett visst tecken, och tvärtom. Funktionen ICHAR(A) ger numret för tecknet i textsträngsvariabeln A, medan CHAR(I) ger tecknet som svarar mot numret I, utgående från intern (maskinberoende) representation. De båda funktionerna IACHAR(A) och ACHAR(I) arbetar däremot med ASCII-koden.
I Fortran 90 tillkom ytterligare ett antal användbara funktioner för texthantering. Dessa finns, tillsammans med ovan nämnda, uppräknade i Appendix 5, avsnitten 4 och 5. De båda ADJUSTL och ADJUSTR vänster- respektive högerjusterar en sträng (dvs flyttar eventuella inledande respektive avslutande blanka men behåller längden), medan TRIM kortar av strängen genom att ta bort avslutande blanka. Längden av en sträng erhålles med LEN, medan LEN_TRIM ger längden utan avslutande blanka. Observera att LEN kan tillämpas på en deklarerad sträng som ej har tilldelats ett värde, i det fallet blir naturligtvis LEN_TRIM noll. Funktionen REPEAT användes för att upprepa en sträng, medan funktionerna INDEX, SCAN och VERIFY ger positionen för ett visst element, se Appendix 5 för detaljer.
Litet ytterligare om texthantering ges i det nytillkomna avsnittet om funktioner med textsträng av antagen längd som resultat.
INTEGER A, B, C
A = 4HKarl
B = 4H Joh
C = 4Han
WRITE(*,10) A, B, C
10 FORMAT(3A4)
END
Metoden var inte speciellt flyttbar (portabel) eftersom antalet bokstäver som ryms i ett
ord varierar mellan olika datorsystem. Vid utmatningen ovan måste ett explicit
FORMAT användas
för att få textutmatning, annars presenteras innehållet i de tre heltalsvariablerna
A, B och C som tre heltal, dvs om WRITE(*,*) användes i stället för WRITE(*,10).
Mer om Format följer i nästa kapitel.
Man kan tilldela nya värden till ovanstående variabler med satser som
IF (X) 20, 30, 40
20 C = A
GO TO 50
30 C = 4HBo
GO TO 50
40 C = B
50 CONTINUE
Det är dock mycket väsentligt här att man bara gör text-tilldelningar mellan
variabler av samma datatyp, annars sker en omvandling mellan olika numeriska typer, varvid texten
blir helt oläslig. I nedanstående fall erhålles på Sun utmatningen Karl
JohNÂÜ@, eftersom jag nu infört flyttalsvariabeln D, som sedan satts lika med
heltalsvariabeln C. Satsen D = C kommer därför att medföra en automatisk konvertering
av bitmönstret i C.
INTEGER A, B, C
REAL D
A = 4HKarl
B = 4H Joh
C = 4Han
D = C
WRITE(*,10) A, B, D
10 FORMAT(3A4)
END
Däremot fungerar det om samtliga variabler är flyttal av samma precision, men ej om
jag blandar enkel och dubbel precision.
Inläsning av CHARACTER(LEN=1) med A5
ABCDE blir E (dvs sista tecknet vinner)
Inläsning av CHARACTER(LEN=5) med A5
ABCDE blir ABCDE
A blir A
A C blir A C
Inläsning av CHARACTER(LEN=5) med A1
ABCDE blir A (dvs första tecknet vinner)
Den fullständiga texten till standarden, liksom implementering i standard Fortran 90 och två exempel, finns tillgängliga elektroniskt.
Programmen i exemplen ovan definierar ord såsom åtskilda av blank (mellanslag), komma, punkt, utropstecken, frågetecken eller postslut (radslut). De bör därför kunna fungera även på svenska texter.
Ett liknande ämne är funktioner med textsträng av antagen längd som resultat, men detta begrepp försvinner vid revisionen nästa årtusende.