Inn og ut i C/C++ 1. Inn og ut i C/C++



Like dokumenter
Del 1 En oversikt over C-programmering

Kapittel 1 En oversikt over C-språket

2. Pekere og referanser.

HØGSKOLEN I SØR-TRØNDELAG Avdeling for informatikk og e-læring - AITeL

1. Grunnleggende C Introduksjon til kurset og til C++ Innhold

Del 4 Noen spesielle C-elementer

TDT4102 Prosedyre og Objektorientert programmering Vår 2014

HØGSKOLEN I SØR-TRØNDELAG

Bruk av class Scanner, FileWriter og Formatter som alternativ til EasyIO i INF1000.

Pekere og referanser.

Del 2 Tabeller, arrays, strenger

HØGSKOLEN I SØR-TRØNDELAG Avdeling for informatikk og e-læring - AITeL

TDT4102 Prosedyre og Objektorientert programmering Vår 2015

Dagens tema. C-programmering. Nøkkelen til å forstå C-programmering ligger i å forstå hvordan minnet brukes.

Grunnleggende C++ Introduksjon til kurset og til C++

TDT4102 Prosedyreog objektorientert programmering Vår 2016

HØGSKOLEN I SØR-TRØNDELAG

Programmeringsspråket C

Oblig2 - obligatorisk oppgave nr. 2 (av 4) i INF1000 v2008

Programmeringsspråket C Del 2

TDT4105 Informasjonsteknologi, grunnkurs. Introduksjon til programmering i Matlab. Rune Sætre / Anders Christensen {satre, anders}@idi.ntnu.

Litt om Javas håndtering av tall MAT-INF 1100 høsten 2004

Programmeringsspråket C

1 ØVING I WINDOWS FRA CHRISTIAN ANDOLO

Programmering i C++ Løsningsforslag Eksamen høsten 2005

Programmeringsspråket C

Eksamen. Objekt-orientert programmering KLASSE(R): 02HIND* 02HDMU* 02HINE* 02HING* 01HINGA 02HSIV5 02HGEOMAA

3 emner i dag! INF1000 Uke 5. Objekter og pekere. null. Litt om objekter, pekere og null Filer og easyio Litt mer om tekster

HØGSKOLEN I SØR-TRØNDELAG

Kort om meg. INF1000 Uke 2. Oversikt. Repetisjon - Introduksjon

TDT4102 Prosedyre og Objektorientert programmering Vår 2014

Oversikt. Introduksjon Kildekode Kompilering Hello world Hello world med argumenter. 1 C programmering. 2 Funksjoner. 3 Datatyper. 4 Pekere og arrays

Oblig 4Hybelhus litt mer tips enn i oppgaven

TDT4102 Prosedyreog objektorientert programmering Vår 2016

Oversikt. INF1000 Uke 1 time 2. Repetisjon - Introduksjon. Repetisjon - Program

Oblig2 - obligatorisk oppgave nr. 2 (av 4) i INF1000 v2009

Kontinuasjonseksamen

Spørsmål fra forrige forelesning. INF1000 Forelesning 7. Oppførselen til inword()/inint()/etc. Operator-presedens i Java

HØYSKOLEN I OSLO, AVDELING FOR INGENIØRUTDANNING

TDT4102 Prosedyre og Objektorientert programmering Vår 2015

INF1000 undervisningen INF 1000 høsten 2011 Uke september

Sprettende ball Introduksjon Processing PDF

Oversikt. INF1000 Uke 2. Repetisjon - Program. Repetisjon - Introduksjon

ITGK - H2010, Matlab. Repetisjon

INF5110. Oblig 2 presentasjon

Oppgavene 1, 2, 4, 5, 6, 9, 12 og 13 passer best til å løses ved en datamaskin.

Kontinuasjonseksamen

Høgskolen i Gjøvik Institutt for informatikk og medieteknikk E K S A M E N. Grunnleggende programmering

Høgskolen i Gjøvik Avdeling for informatikk og medieteknikk. Eksamen. Objekt-orientert programmering

Oblig2 - obligatorisk oppgave nr. 2 (av 4) i INF1000 h2006

Python: Variable og beregninger, input og utskrift. TDT4110 IT Grunnkurs Professor Guttorm Sindre

INF1000 Behandling av tekster

2 Om statiske variable/konstanter og statiske metoder.

C++ versus Java 1. C++ versus Java

K O N T I N U A S J O N S E K S A M E N

TDT4102 Prosedyre og Objektorientert programmering Vår 2014

Kontinuasjonseksamen

TDT4105 Informasjonsteknologi, grunnkurs. Introduksjon til programmering i Matlab. Rune Sætre / Anders Christensen {satre,

Kontinuasjonseksamensoppgave i IMT1082 Objekt-orientert programmering

Dagens tema C, adresser og pekere

Inf109 Programmering for realister Uke 5. I denne leksjonen skal vi se på hvordan vi kan lage våre egne vinduer og hvordan vi bruker disse.

Oblig 4 (av 4) INF1000, høsten 2012 Værdata, leveres innen 9. nov. kl

TDT4105/TDT4110 Informasjonsteknologi grunnkurs:

UNIVERSITETET I OSLO

2 Om statiske variable/konstanter og statiske metoder.

Beskrivelse av programmeringsspråket Compila15 INF Kompilatorteknikk Våren 2015

Dagens tema. C-programmering. Nøkkelen til å forstå C-programmering ligger i å forstå hvordan minnet brukes.

Argumenter fra kommandolinjen

Lese fra fil. INF1000 : Forelesning 5. Eksempel. De vanligste lesemetodene. Metoder:

Høgskolen i Gjøvik. Eksamen. Objekt-orientert programmering 98HINDA / 98HINDB / 98HINEA 98HDMUA / 98HDMUB

8. Operator overloading

Tre måter å lese fra terminal. Java 4. Eksempel. Formatert utskrift til skjerm

Kapittel 1. Datamaskiner og programmeringsspråk. 1.1 Programmering

TDT4105/TDT4110 Informasjonsteknologi grunnkurs:

LITT OM OPPLEGGET. INF1000 EKSTRATILBUD Stoff fra uke September 2012 Siri Moe Jensen EKSEMPLER

Alle hele tall g > 1 kan være grunntall i et tallsystem.

Løsningsforslag ukeoppg. 6: 28. sep - 4. okt (INF Høst 2011)

E K S A M E N. Grunnleggende datakunnskap og programmering 02HIND*, 02HINE*, 02HDMU*, 02HING*, 02HGEOMAA, 02HSIV5

Oblig2 - obligatorisk oppgave nr. 2 (av 4) i INF1000

Transkript:

Tore Berg Hansen 3.9.2004 Opphavsrett: Forfatter og Stiftelsen TISIP Lærestoffet er utviklet for faget LV194D C++ for javaprogrammerere 1. Resymé: Vi skal her se litt nærmere på hvordan vi får data inn via tastaturet og ut på skjermen. I en senere leksjon skal vi se på inn/ut til fil. Innhold 1.1. INNLEDNING... 2 1.2. FORMATTERT UT MED PRINTF... 2 1.3. FORMATTERT INN MED SCANF... 6 1.4. STREAM INN/UT MED OBJEKTER... 6 1.4.1. Generelt... 6 1.4.2. Formattering av inn/ut... 7

1.1. Innledning Verken C eller C++ har innebygget i språket mekanismer for å håndtere inn/ut. Det gjøres derfor ved hjelp av biblioteker som leveres med kompilatorene. I prinsippet er det tre typer inn/ut. - stream inn/ut - lav-nivå inn/ut - konsoll og port inn/ut Stream er et sentralt begrep når det gjelder inn/ut i C og C++. En stream kan oppfattes som en smart fil som er mottaker eller avsender av bytes. Drivere for forskjellige inn/ut enheter kan samspille med en stream. På den måten kan inn/ut håndteres likt, sett fra programmet, enten det dreier seg om diskfiler, tastatur, skjerm, skriver eller andre kommunikasjonsporter. Stream inn/ut er bufret og kan formatteres. I C håndteres stream inn/ut ved hjelp av funksjoner. I C++ kan man bruke de samme funksjoner som i C, men mer elegant er det å bruke objekter knyttet til de forskjellige stream. Lav-nivå inn/ut håndteres av funksjoner som benytter operativsystemet direkte. Konsoll og port inn/ut har funksjoner som direkte skriver til skjerm, leser fra tastatur eller leser/skriver til bestemte inn/ut porter, f.eks skriver. Vi skal ikke se på alle disse mulighetene her, men ta for oss noen av de mest brukte funksjoner for stream inn/ut og spesielt objekter for inn/ut. 1.2. Formattert ut med printf printf har en prototype som vist nedenfor. int printf( const char *format [, argument]... ); Funksjonen har et eller flere argumenter. Det første argumentet er en tekststreng med formatteringsinformasjon. (Legg merke til at argumentet for tekststrengen er av typen peker til char). Deretter følger et valgfritt antall argumenter. Funksjonen returnerer antallet tegn som skrives ut eller et negativt tall i tilfelle en feil. Her er noen eksempler. printf( Resultatet er %5.2f, resultat); Hvis nå resultat er et flyttall med verdi 23,542, så vil det på skjermen bli skrevet Resultatet er 23.54 I tillegg til teksten er det hva som står bak prosenttegnet (%5.2f) som bestemmer formatteringen. I dette tilfellet gjelder formatteringen flyttallet som følger som argument. Det side 2 av 12

er mange forskjellige muligheter for å formattere både tekst og tall. Den generelle oppbyggingen er slik Angir justering, skriving av blanke, fortegn og spesialtegn. Angir maksimalt antall tegn for hele eller deler av utskriften eller minimum antall tegn for heltall. (Tolkning avhenger av type). %[flagg] [bredde] [.presisjon] [{h l I64 L] type Markerer start på formatspesifikasjon Angir minimum antall tegn i utskrift. Tilleggsinformasjon om størrelse på argumentet. Bestemmer om tilhørende argument skal tolkes som tegn (char), streng eller tall. Hakeparenteser, [ ], betyr at tegnet er valgfritt. Hvis tegnet ikke tas med brukes en standardverdi. Tabellen viser hvilke tegn som kan være flagg og betydningen. Flagg Tolkning Standardtolking - Juster resultatet mot venstre. Justeres mot høyre. + Sett pluss eller minus foran hvis utverdien er et tall med fortegn. 0 Legger til nuller foran inntil minimumsbredden er nådd. Ignoreres for heltall. Fortegn bare foran negative tall. Ingen nuller foran. blank Setter inn blanke foran et positivt tall. Ingen blanke foran. # Brukt sammen o, x eller X settes 0, 0x eller 0X foran. (o for oktal, x for hexadesimalt tall) Brukt sammen med e, E eller f tvinges utverdien til å inneholde et desimalskilletegn. Brukt med g eller G tvinges utverdien til å inneholde et desimalskilletegn. Bare skilletegn hvis det verdien tilsier det. Bare skilletegn hvis verdien tilsier det. Fjerner nuller bak skilletegnet. Har ingen mening sammen med c, d, i, u, eller s. side 3 av 12

Bredde er et tall som angir minimum antall tegn som skal skrives ut. Hvis antall tegn som skal skrives ut er mindre enn dette minimum, legges det til blanke. Hvis 0 kommer foran bredde, legges det til nuller. Hvis antallet tegn blir større enn bredde, skrives alle tegn ut. Dvs at utskriftsfeltet øker i størrelse. Hvis man skriver ut kolonner av tall fører det til en rotete utskrift. Presisjon er et positivt heltall. Det spesifiserer antall tegn som skal skrives, antallet desimalplasser eller antallet signifikante siffer. Flyttall blir avrundet. Tabellen nedenfor gir nærmere detaljer. Type Tolkning Standard tolkning c, C Ingen effekt. Tegn (Char) skrives ut. d, i, u, o, x, X Spesifiserer minimum antall tegn som skal skrives ut. Hvis antallet tegn mindre, legges det til nuller til venstre, inntill minimumsverdien nås. Verdien avkortes ikke hvis antallet siffer er større enn minimumstallet. Standard er 1. e, E Angir antall siffer etter desimalskilletegnet. f Angir antall siffer etter desimalskilletegnet. Hvis det er et desimalskilletegn, vil det bli skrevet ut minst et siffer foran det. Verdier blir avrundet. g, G Angir maksimum antall signifikante siffer. s, S Spesifiserer maks antall tegn som skal skrives ut. Overskytende tegn skrives ikke ut. Standard er seks. Hvis 0 angis eller. ikke følges av noe tall, blir ingen siffer etter skilletegnet skrevet ut. Standard er seks. Hvis 0 angis eller. ikke følges av noe tall, blir ingen siffer etter skilletegnet skrevet ut. Seks signifikante siffer. Kutter bort eventuelle nuller bakerst. Tegn skrives ut inntil nulltegnet blir funnet. Type skal tolkes som i følgende tabell. Tegn Type Format c int Spesifiserer en byte. C int Microsoft spesifikk. d int Heltall med fortegn. i int Heltall med fortegn. side 4 av 12

Tegn Type Format o int Oktalt heltall uten fortegn. u int Desimalt heltall uten fortegn. x int Heksadesimalt heltall uten fortegn, med abcdef. X int Heksadesimalt heltall uten fortegn, med ABCDEF. e double Vitenskapelig format på formen [ - ]d.dddd e [fortegn]ddd. d er et enkelt desimalsiffer. E double Samme som e, men med stor E. f double Benevnt verdi på formen [ - ]dddd.dddd. d er et desimalsiffer. Antallet siffer foran desimalskilletegnet avhenger av tallets størrelse. Antallet siffer etter desimalskilletegnet er gitt av angitt presisjon. g double Benevnt verdi som skrives i enten f eller e format. Det som gir mest kompakt form brukes. G double Samme som g, men eventuelt med stor E. n Peker til heltall Antall skrevet så langt blir lagret i et heltall med adresse angitt av argumentet. p Peker til void Skriver ut adressen som det pekes på av argumentet. s String Skriver ut null-terminert streng. S String Skriver ut null-terminert streng. Microsoft spesifikk. [{h l I64 L] er Mikrosoft spesifikke og ikke ANSI-kompatible. De brukes for blant annet å angi nærmere om det dreier seg om long int, long unsigned int, short int osv. side 5 av 12

1.3. Formattert inn med scanf scanf er motsatsen til printf. Den har prototypen int scanf( const char *format [, argument]... ); Vi tar ikke alle detaljer om denne funksjonen her. Formatteringen er stort sett likt den man har for printf. Det vil si at scanf leser data fra en stream og tolker disse dataenes format i henhold til formatspesifikasjonen. prinf skriver data til en stream i henhold til formatspesifikasjonen. Argumentene er pekere. (Det må de være for at man skal få data inn. Argumenter overføres som verdier i C.) Her følger et lite eksempel på bruk av scanf. #include <stdio.h> void main( void ) { int i; int resultat; float fp; char c; char s[81]; printf( \n\nsett inn et heltall, en char og en tekststreng\n ); resultat = scanf( %d %f %c %s, &i, &fp, &c, s); printf( ( \nantallet felt lest er %d\n, resultat); printf( Dette ble lest: %d %f %c %s\n, i, fp, c, s); Øverst har vi inkludert biblioteket, stdio.h, som inneholder de aktuelle funskjonene. Nyere versjoner av kompilatoren bruker cstdio, uten.h. Vi skal i en senere leksjon se nærmere på denne og andre nye ting i C++. 1.4. Stream inn/ut med objekter 1.4.1. Generelt Når man skriver programmer i C++ er det mer elegant og objektorientert å bruke iostream klassehierarkiet når man skal ha data inn og ut av programmer. På toppen i dette hierarkiet sitter klassen ios. Teknisk sett er den ikke en abstrakt klasse, men man vil sjelden bruke objekter fra denne klassen. I stedet bruker man subklasser for bestemte formål. Figuren nedenfor viser klassehierarkiet. side 6 av 12

ios streambuf istream ostream istream_withassign iostream ostream_withassign iostream_withassign Inn/ut er bufret. Derfor bruker ios en bufferklasse, streambuf. ios klassene står for formatteringen, mens streambuf sørger for lavnivå bufringen av data. På nivået under ios ligger to klasser, en som håndterer data (strøm) inn og en som håndterer data ut. Klassen iostream ser man håndterer både inn og ut streams. Klassene som har fått hengt på navnet _withassign er varianter som har den egenskap at de kan tilordnes forskjellige fysiske utenheter i kjøre-tid. cin er et forhåndsdefinert objekt fra istream_withassign. Dette objektet er normalt tilordnet tastaturet, men kan i kjøretid tilordnes (reassign) midlertidig en diskfil. Tilsvarende for cout som er et objekt fra klassen ostream_withassign. Det kan også tilordnes en annen utenhet enn skjermen i kjøretid. Mest aktuelt vil være en diskfil. To andre forhåndsdefinerte objekter er cerr og clog. De sender henholdsvis feilmeldinger og loginformasjon til skjerm. Dvs at de er tilordnet (assigned) skjermen, men kan altså i kjøretid tilordnes andre enheter som f.eks diskfiler. 1.4.2. Formattering av inn/ut Det er to mekanismer man kan bruke når man skal formattere inn/ut når man bruker objektene cin og cout: ved hjelp av medlemsfunksjoner i ios klassen ved å sette manipulatorer inn i inn/ut strømmen Vi skal se på noen eksempler. Først bruk av medlemsfunksjoner. #include <iostream> void main( void ) { double verdier [] = {2.33, 43.56, 534.7, 3596.32 ; for (int i = 0; i < 4; i++ ) { side 7 av 12

std::cout.width( 10 ); std::cout << verdier[i] << std::endl; Dette programmer lager denne utskriften. Vi merker oss følgende. Det skrives ut fire verdier fra en tabell. Bredden på utskriften settes til 10 tegn. (cout.width( 10 )). Tall som krever mindre enn 10 tegn blir høyrejustert i utskriftsfeltet og blanke settes inn til venstre. Hvis vi i for-løkken setter inn cout.fill( * )i tillegg, blir utskriften slik: Dere ser effekten. Legg også merke til at vi i programmet må inkludere filen iostream og kvalifisere med std::. Det siste må vi gjøre hvis vi bruker kompilatorer som følger nyere standarder av C++ med namespace. Hvis du har eldre versjoner av kompilatoren må du skrive side 8 av 12

#include <iostream.h> Dette er ting vi skal se på i detalj senere. Så tar vi et eksempel med manipulatorer. Her følger den endrede kildekode. #include <iostream> #include <iomanip> using namespace std; void main( void ) { double verdier [] = {2.33, 43.56, 534.7, 3596.32 ; for (int i = 0; i < 4; i++ ) { cout << setw(10) << setfill('*') << verdier[i] << endl; Dette programmet produserer samme utskrift som ovenfor. Legg også merke til denne setningen using namespace std; Den bruker vi hvis vi vil slippe å kvalifisere alle ting i standardbibliotekene i nyere versjoner av kompilatoren. Som antydet flere steder kommer vi tilbake til disse tingene senere. Foreløpig får dere bare følge retningslinjene, slik at øvingsprogrammene dere skriver kompilerer. Programeksemplene i leksjonen kan følge både gammel og ny formalisme. I tabellen som følger er det listet de viktigste medlemsfunksjoner og manipulatorer. Medlemsfunksjon Manipulator Mening width() fill() precision() setf() unsetf setw() setfill() setprecision() setiosflags() resetiosflags() feltbredde for neste ut Fylltegn flyttall presisjon sett flagg resett flagg setf og setiosflags bruker såkalte ios-flagg. Disse er tall som representerer forskjellige egenskaper ved formatteringen. Tallene er gitt symbolske navn (egentlig er de en enum type) og er lagt inn i klassen ios. side 9 av 12

Her følger en oversikt over de viktigste flaggene. Flagg ios::skipws ios::left ios::right Tolkning Hopp over blanke i input Venstrejustering i feltet. Sett inn fyll-tegn (blank er standard) Høyrejustering i feltet. Sett inn fyll-tegn (blank er standard) ios::dec Formatter som desimaltall (basis 10). ios::oct Formatter som oktaltall (basis 8). ios::hex Formatter som heksadesimaltall (basis 16). ios::showpoint ios::uppercase ios::showpos ios::scientific ios::fixed Skriv ut desimalskilletegn og eventuelt etterfølgende nuller. Skriv ut de heksadesimale siffer som store bokstaver (ABCDEF) Sett inn + foran positive tall. Vis flyttall i vitenskapelig format. Vis flyttall i fast format. Vi behøver bare å forholde oss til disse symbolske navnene. Men ios::scientific har f.eks verdien 0x0800 (heksadesimal form). Legg merke til bruken av operatoren :: (to kolon) mellom klassenavnet og navnet på flagget. I denne sammenheng er :: rekkeviddeoperatoren. Får å få tak i et medlem definert i en klasse må vi angi klassenavn og medlemsnavn atskilt med rekkeviddeoperatoren. Noen flere eksempler. #include <iostream.h> #include <iomanip.h> void main( void ) { double verdier [] = {2.33, 43.56, 534.7, 3596.32 ; for (int i = 0; i < 4; i++ ) { cout << setw(20) << setfill('*'); cout << setiosflags(ios::fixed ios::right); cout << setprecision (2); cout << verdier[i] << endl; Dette programmer produserer denne utskriften. side 10 av 12

Utskriftsfeltet er satt til 20 tegn totalt, presisjon til 2, hvilket gir to siffer etter desimalskilletegnet. Fylltegnet er * for å gjøre det synlig i utskriften (det normale ville være blank). Alle tall får det samme antall siffer etter skilletegnet. Om nødvendig fylles på med nuller. Det blir tydeligere hvis vi øker presisjonen til 4. I stedet for manipulatorer kan vi bruke medlemsfunksjoner. Dette eksemplet gir samme utskrift som ovenfor: #include <iostream.h> void main( void ) { double verdier [] = {2.33, 43.56, 534.7, 3596.32 ; for (int i = 0; i < 4; i++ ) { cout.setf(ios::fixed); cout.precision( 4); cout.width (20); cout.fill('*'); cout << verdier[i] << endl; side 11 av 12

Endrer vi til cout.setf(ios::scientific) blir utskriften slik I disse programeksemplene har vi brukt endl i utskriftsetninger. Det er en manipulator som ikke trenger iomanip.h. Det endl gjør er å sørge for linjeskift og start på ny linje. Dvs at den brukes i stedet for tegnet \n. Hva skal man så bruke? Medlemsfunksjoner eller manipulatorer? Det kan være en smakssak. En fordel med manipulatorer er at du kan lage dine egne. Du kan for eksempel slå sammen manipulatorer som ofte brukes til en manipulator, eller du kan lage spesielle manipulatorer for enheter som du ikke kan bruke de ferdigdefinerte manipulatorene på. side 12 av 12