Alla variabler är lagrade i datorn med 1 och 0, men representerar heltal, flyttal, logiska variabler eller bokstäver och andra skrivtecken.
Vid in/utmatning måste därför information finnas om vilken variabeltyp det är frågan om!
Följande värden på flyttalet A, dubbelprecisionstalet D, komplexa talet C, heltalet I, logiska variabeln L samt tecknet X,
A = 1.0 D = 2.D0 C = (3.0 , 4.0) I = 25 L = .TRUE. X = 'X'ger med utskriftskommandot
WRITE(*,30) A, D, C, I, L, X 30 FORMAT('1 A = ',F8.3,' D = ',F20.16,/ ,' C = ',2F8.3,' I = ',I3,' L = ',L1,' X = ',A)först ny sida och sedan
A = 1.000 D = 2.0000000000000000 C = 3.000 4.000 I = 25 L = T X = XHär är en förklaring på sin plats. Utskriften av talen i listan sker utnyttjande formatet med nummer 30, vilket dels innehåller information om vilken text som skall skrivas mellan de olika talen, dels hur de olika talen skall skrivas ut. Texten mellan de olika talen, samt eventuellt inledande och avslutande text, skrivs direkt i formatet utnyttjande vanliga apostrofer '.
I ovanstående exempel skrivs det första talet A ut med formatet F8.3, vilket betyder ett flyttal med totalt åtta positioner, varav tre för decimalerna. Notera att utrymme behövs för inledande blank, tecken, heltalssiffra samt decimalkomma, varför F7.3 är tänkbart, men ej F5.3. Det andra talet D skrives ut med formatet F20.16, vilket betyder ett flyttal med totalt 20 positioner, varav 16 för decimalerna. Notera att utrymme även här behövs för inledande blank, tecken, heltalssiffra samt decimalkomma. Det komplexa talet C skrivs ut som två tal, realdelen och imaginärdelen.
Heltalsutmatning betecknas med I och antalet tecken i fältet. Motsvarande gäller logiska variabler och textsträngsvariabler.
En mindre variant på samma utmatning är
WRITE(*,40) A, D, C, I, L, X 40 FORMAT('1 A = ',E18.3,' D = ',D28.16,/ ,' C = ',2E18.3,' I = ',I1,' L = ',L1,' X = ',A4)med resultatet
A = 0.100E+01 D = 0.2000000000000000D+01 C = 0.300E+01 0.400E+01 I = * L = T X = XHär är utrymmet för litet för heltalet 25, vilket därför markeras med en stjärna. Notera vidare att vi nu använder formatbokstäverna E och D för att beteckna flyttal med exponent. Fortfarande så anger den sista siffran antalet decimaler, men nu måste vi notera att exponentdelen tar fyra positioner. Både E och D betyder 10 upphöjt till, D är bara en indikation på att dubbel precision använts.
Man kan byta ut E som markering för utmatning på exponentform mot ES, och får då en vetenskaplig (Scientific) form, med utmatning av en siffra skild från noll före decimaltecknet. Om man i stället byter ut E mot EN får man en teknisk (ENgineering) form med en till tre siffror före decimaltecknet, och en exponent jämnt delbar med tre. Om det utmatade värdet är noll erhålles samma utmatning från ES och EN som från E.
Vid användning av vanlig formatstyrd in/utmatning kan man under vissa operativsystem, förutom att ange en fullständig specifikation, alternativt ge bara respektive FORMAT-bokstav. Betydelsen, dvs antalet positioner i fältet, är då systemberoende.
blank Ny rad + Ej ny rad (överskrivning, finns ej på alla skrivare) 0 Dubbel radframmatning 1 Ny sidaPå en del skrivare används ytterligare tecken, siffrorna är ofta vertikala tabulatorer.
OBS: Utmatning med FORMAT(I5) eller F7.3 eller 1PE8.2 kan medföra utmatning av en förfärlig massa papper med nästan inget tryck på, dvs "KARTONGBYTE". Ge därför alltid en explicit blank först i alla FORMAT avsedda för utmatning (om ej annat styrtecken önskas). Erhålles med 1X eller ' ' eller 1H .
Använd därför aldrig samma FORMAT för både in- och utmatning.
Om man vid VAX/VMS först önskar utmatning på fil och sedan på papper bör filtypen .DAT användas, det är bara då som styrtecknen användes automatiskt.
Under UNIX är det litet bökigt att att utnyttja ovanstående styrtecken, det sker på olika sätt hos olika leverantörer.
f77 -vms prog.foch får då styrtecknen bortrensade från utmatningen på skärmen.
OPEN(1, FILE = 'utfil', CARRIAGECONTROL = 'FORTRAN')och får då en fil som utskriven med laserskrivaren ger ny sida och andra egenskaper hos styrtecknen på rätt sätt. Kommandot CARRIAGECONTROL är dock ej standard, varför kompileringsfel erhålles under andra system.
f90 -vms prog.f90och får då styrtecknen rätt hanterade vid utmatning på skärmen.
OPEN(1, FILE = 'utfil', CARRIAGECONTROL = 'FORTRAN')och får då en fil som utskriven med laserskrivaren ger ny sida och andra egenskaper hos styrtecknen på rätt sätt. Kommandot CARRIAGECONTROL är dock ej standard, varför kompileringsfel erhålles under andra system.
fpr < utfil | lpr -Pskrivare -w132Ovanstående metod fungerar på de flesta leverantörers system, en del kallar dock fpr för asa. Gör gärna man fpr eller man asa. Den sista väljaren ovan, -w132, ger utmatning på bredden i stället för på tvären, och kan naturligtvis utelämnas.
fpr < utfil > utfil2 ens utfil2varefter man i dialogen från ens svarar Landscape för att få utmatning på bredden.
WRITE(*,*) utdatadär utdata dels är de variabler som skall matas ut, men även kan vara kompletterande text inom apostrofer eller citat-tecken. Se även en något utförligare diskussion i avsnitt 3.7 Enkel in- och utmatning samt nedanstående avsnitt om liststyrd inmatning.
Användning av Hollerith-konstruktionen vid liststyrd utmatning skall undvikas, den fungerar dock under en del Fortran 77 system.
WRITE(*,*) 32H Mycket olämpligt utmatningssättFöljande tre utmatningssätt är tillåtna, men det första av dem är både jobbigt och föråldrat.
WRITE(*,60) 60 FORMAT(25H Olämpligt utmatningssätt) WRITE(*,70) 70 FORMAT(' Lämpligt utmatningssätt') WRITE(*,*) ' Lämpligt utmatningssätt'
Den innebär att in/utmatning sker i det format som variablerna lagras i datorn, dvs i princip som binära siffror och packade på ett sådant sätt att den lagrade informationen är nästan oläslig på skärm eller papper. Denna lagringsmetod har tre stora fördelar:
För att skriva ut oformaterat ger man först ett kommando för att öppna en fil för oformaterad utmatning, se vidare i nästa kapitel. Vi väljer att låta den oformaterade utmatningen ske på enhetsnummer 1 och på en ny fil med namnet utfil.
OPEN(1, FILE='utfil', STATUS='NEW', FORM = 'UNFORMATTED')Själva utmatningen sker med en skrivsats som innehåller enhetsnumret inom parentesen, men inget ytterligare. Listan över de olika variablerna skrives på vanligt sätt.
WRITE(1) A, B, C, DNär man är färdig med utmatningen bör man stänga filen. Vissa system stänger automatiskt alla filer när programmet avslutas på normalt sätt, men ej alltid vid avbrott på grund av fel.
CLOSE(1)Vid en eventuell inläsning av dessa data är det väsentligt att de variabler till vilka de inlästa talen tilldelas är av samma typ (och längd) som de skrivna. Man måste naturligtvis ha enheten öppnad innan man kan läsa från den.
READ(1) E, F, G, H
Som framgår av nedanstående exempel kan man ange antalet element som skall matas ut med en faktor (konstant) framför aktuellt format.
INTEGER :: I REAL, DIMENSION(10) :: A WRITE(*,20) A ! Utskrift av alla 10 elementen 20 FORMAT(10F10.3) WRITE(*,30) A(1), A(2), A(7) ! Utskrift av 3 element 30 FORMAT(3F10.3) WRITE(*,50) (A(I), I = 1,9,2) 50 FORMAT(5F10.3) WRITE(*,60) A(1)*A(2)+I, SQRT(A(3)) 60 FORMAT(2F10.3)Konstruktionen (A(I), I = nr1, nr2, nr3) kallas för en implicit DO-slinga, och den fungerar nästan som en vanlig explicit DO-slinga
DO I = nr1, nr2, nr3 WRITE(*,50) A(I) END DOmen med den skillnaden att den explicita slingan skriver ut ett tal per rad, medan den implicita i detta fall skriver fem tal per rad. Skillnaden beror på att varje värde på styrvariabeln I ger upphov till ett nytt anrop av utskriftsrutinen, varvid formatet användes på nytt från början. Man kan säga att varje anrop av WRITE skriver ut minst en ny rad (post) och att på motsvarande sätt varje anrop av READ läser in minst en rad. Konstruktionen med en implicit DO-slinga kan bara användas i WRITE och READ satser.
En viktig egenskap hos format är att man kan ge "för många" utan att det ställer till någon skada. I fallet ovan kan formaten med nummer 30, 50 och 60 samtliga ersättas med det längsta, nämligen det med nummer 20. Om antalet format-poster är för stort jämfört med antalet utmatningsposter så användes inte de överblivna, om det i stället är för litet så börjar utmatningen om från början (jämför dock nedan) av formatet. Exempel på möjliga formatkonstruktioner med motsvarande ut-lista är följande,
10F12.3 A 4(I5,F10.2) (I(J),A(J), J = 1,4)Den senare skriver ett heltal I(1), ett flyttal A(1), ett ytterligare heltal I(2), ett flyttal A(2), osv. Formaten kan kapslas
4(I5,3F10.2) (I(J),A(J),B(J),C(J), J = 1, 4)Om formaten "tar slut" börjar det om från början (men på en ny rad)
(10I8) (I(J), J = 1, 1000)eller från den vänsterparentes som svarar mot den näst sista högerparentesen (eller dess repetitionsfaktor, om sådan finns)
(2I5, 3(I2,2(I1,I3)), 2(2F8.2,I2)) ^ ^ ^ Näst sista högerparentes Repetitionsfaktor till denna parentesI detta exempel matas således först 17 heltal ut, dvs (2+3(1+2*2)), därefter följer två uppsättningar med vardera två flyttal och ett heltal, därefter följer ny rad med två uppsättningar med vardera två flyttal och ett heltal, följt av ny rad med två uppsättningar med vardera två flyttal och ett heltal, osv, så länge som utdata räcker till.
Det kan även inträffa att man vill ge "för få" tal att skrivas ut, som i nedanstående exempel.
WRITE(*,10) A, B, C 10 FORMAT(' A = ', F6.3, ' B = ', F6.3, ' C = ', F6.3)Detta ger en trevlig utmatning
A = 1.123 B = -2.345 C = 3.456men om man bara har två tal att skriva ut erhålles den trista utskriften
A = 1.123 B = -2.345 C =dvs C = står där i sin ensamhet. Om man i stället sätter in kolon efter varje post i formatet och således använder
10 FORMAT(' A = ', F6.3,:, ' B = ', F6.3,:, ' C = ', F6.3)så blir utskriften den önskade
A = 1.123 B = -2.345
REAL A DOUBLE PRECISION D COMPLEX C INTEGER I LOGICAL L CHARACTER*1 X READ(5,*) A, D, C, I, L, Xpå indata
1. 2. 3. 4 T 'Z'ger med
WRITE(6,*) A, D, C, I, L, Xutskriften
1.000000, 2.0000000000000000 (3.000000, 0.000000E+00), 4, TZmen samma lässats på indata
1. 2. (3., 4.) 5 .F. 'Y'ger utskriften
1.000000, 2.0000000000000000 (3.000000, 4.000000), 5, FYoch på indata
1. 2. 3. 4. X 'Z'erhålles
^ ?Illegal character in dataeftersom X inte är ett logiskt värde, och slutligen med
1. 2. 3. 4. T 'T'erhålles
1.000000, 2.0000000000000000 (3.000000, 0.000000E+00), 4, TTRegler för liststyrd inmatning.
15*7.0, femton flyttals-sjuor 13*, tretton överhoppade variabler
READ(5,...,ERR=snr1, END=snr2) WRITE(5,...,ERR=snr3)Vid paritetsfel och en del andra fel (implementationsberoende) flyttas exekveringen till sats snr1 respektive sats snr3.
På DEC-20 fungerade ERR även då typen på indata ej stämde med variabelns datatyp, den gav då en möjlighet att hoppa tillbaks för ett nytt försök. Ibland ger även filslut återhopp till snr1 (om END=snr2 ej getts).
Vid filslut gäller att END=snr2 ger att exekveringen flyttas till snr2. Ett filslut erhålles med kommandot Kontroll-z eller Kontroll-d. Bra för att avsluta en inläsning.
Nedan visar jag tre olika sätt att ge denna tilldelning. De har alla sina för- och nackdelar.
PROGRAM FORMAT IMPLICIT NONE REAL :: X CHARACTER (LEN=11) :: FORM1 CHARACTER (LEN=*), PARAMETER :: FORM2 = "( F12.3,A )" FORM1 = "( F12.3,A )" x = 12.0 PRINT FORM1, X, ' HELLO ' WRITE (*, FORM2) 2*X, ' HEJ ' WRITE (*, "( F12.3,A )") 3*X, ' HEJSAN ' ENDI PRINT-satsen använder jag en textsträngsvariabel FORM1 med längden 11 som tilldelas sitt värde i en explicit tilldelningssats. Nackdelen med denna metod är främst att man måste manuellt räkna antalet tecken, om man anger ett för litet antal ger NAG:s Fortran 90 kompilator inget kompileringsfel, utan felavbrottet kommer först vid exekveringen.
I den första WRITE-satsen använder jag i stället en textsträngskonstant FORM2. Fördelen är att genom att jag använder PARAMETER ej behöver ge någon explicit längd på konstanten, utan kan ange LEN = *. Nackdelen är att en konstant ej kan ges ett nytt värde.
I den andra WRITE-satsen använder jag i stället direkt en textsträng. Nackdelen är att strängen ej kan återanvändas.