C ++ Tutorial: Lær om input og output

01

av 08

En ny måte å produsere

Programkode
traffic_analyzer / Getty Images

C ++ har veldig høy bakoverkompatibilitet med C, altså kan inkluderes for å gi deg tilgang til printf () funksjon for utgang. Imidlertid er I / O levert av C ++ betydelig kraftigere og enda viktigere type trygt. Du kan fremdeles også bruke scanf () for innspill, men type sikkerhetsfunksjoner som C ++ gir betyr at applikasjonene dine vil være mer robuste hvis du bruker C ++.

I forrige leksjon ble dette berørt med et eksempel som brukte cout. Her vil vi gå inn i litt mer dybde og begynne med output først da det pleier å bli mer brukt enn input.

Iiostream-klassen gir tilgang til objektene og metodene du trenger for både output og input. Tenk på i / o når det gjelder strømmer av bytes - enten å gå fra applikasjonen til en fil, skjermen eller en skriver - som blir skrevet ut, eller fra tastaturet - som skrives inn.

Utgang med Cout

Hvis du kjenner C, kan du kanskje vite det << brukes til å skifte biter til venstre. F.eks. 3 << 3 er 24. F.eks. Venstre skift dobler verdien så 3 venstre skift multipliserer den med 8.

instagram viewer

I C ++, << har vært belastet i ostream-klassen slik at int, flyte, og strengstyper (og deres varianter - f.eks dobles) støttes alle. Slik lager du tekstutdata ved å strenge sammen flere elementer mellom <<.>


cout << "Noe tekst" << intvalue << floatdouble << endl; 

Denne særegne syntaks er mulig fordi hver av << er faktisk en funksjonsanrop som returnerer a henvisning til en strøm gjenstand. Så en linje som ovenfor er faktisk slik


cout. << ("litt tekst"). cout. << (intvalue) .cout. << (floatdouble) .cout. << (endl); 

C funksjonprintf kunne formatere utdata ved hjelp av formatspesifikasjoner som% d. I C ++ kan cout også formatere utdata, men bruker en annen måte å gjøre det på.

02

av 08

Bruke Cout til å formatere output

Objektet cout er medlem av iostream bibliotek. Husk at dette må inkluderes i a


#inkludere 

Dette biblioteket iostream er avledet fra ostream (for utgang) og istream for innspill.

formatering av tekstutgang gjøres ved å sette inn manipulatorer i utstrømmen.

Hva er en manipulator?

Det er en funksjon som kan endre egenskapene til utgangsstrømmen (og inngangsstrømmen). På forrige side så vi det << var en overbelastet funksjon som returnerte en referanse til det ringerobjektet, f.eks. cout for output eller cin for input. Alle manipulatorer gjør dette slik at du kan inkludere dem i utdataene << eller innspill >>. Vi skal se på innspill og >> senere i denne leksjonen.


telle << endl; 

endl er en manipulator som avslutter linjen (og starter en ny). Det er en funksjon som også kan kalles på denne måten.


endl (cout); 

Selv om du i praksis ikke ville gjort det. Du bruker det slik.


cout << "Noe tekst" << endl << endl; // To blanke linjer. 

Filer er bare strømmer

Noe å huske på at med mye utvikling i disse dager gjøres i GUI applikasjoner, hvorfor trenger du tekst-I / O-funksjoner? Er ikke det bare for konsoll applikasjoner? Vel, du vil sannsynligvis gjøre fil I / O, og du kan bruke dem der også, men også hva som sendes ut til skjerm trenger vanligvis også formatering. Strømmer er en veldig fleksibel måte å håndtere input og output på og kan fungere med

  • Tekst I / O. Som i konsollapplikasjoner.
  • Strenger. Praktisk for formatering.
  • Fil I / O.

Manipulatorer igjen

Selv om vi har brukt ostream klasse, det er en avledet klasse fra ios klasse som stammer fra ios_base. Denne forfederklassen definerer publikum funksjoner som er manipulatorer.

03

av 08

Liste over Cout-manipulatorer

Manipulatorer kan defineres i inngangs- eller utgangsstrømmer. Dette er objekter som returnerer en referanse til objektet og er plassert mellom par av <<. De fleste av manipulatorene er erklært i, men endl, endene og flush kommer fra . Flere manipulatorer tar en parameter, og disse kommer fra .

Her er en mer detaljert liste.

Fra

  • endl - Avslutter linjen og ringer raskt.
  • slutter - Sett inn '\ 0' ( NULL) inn i strømmen.
  • spyle - Tving bufferen til å sendes ut umiddelbart.

Fra . De fleste er erklært i stamfaren til . Jeg har gruppert dem etter funksjon i stedet for alfabetisk.

  • boolalpha - Sett inn eller trekk ut bool-objekter som "sanne" eller "usanne".
  • noboolalpha - Sett inn eller trekk ut bool-objekter som numeriske verdier.
  • fast - Sett inn flytende punktverdier i fast format.
  • vitenskapelig - Sett inn flytende punktverdier i vitenskapelig format.
  • intern - Intern-rettferdiggjøre.
  • venstre - Venstre-rettferdiggjøre.
  • rett - Høyre rettferdiggjøre.
  • dec - Sett inn eller trekk ut heltallverdier i desimalformat.
  • hex - Sett inn eller trekk ut heltallverdier i heksadesimal (base 16) -format.
  • okt - Sett inn eller trekk ut verdier i oktalt (base 8) format.
  • noshowbase - Ikke prefiks verdi med basen.
  • showbase - Prefiksverdi med basen.
  • noshowpoint - Vis ikke desimaltall hvis ikke nødvendig.
  • showpoint - Vis alltid desimaltall når du setter inn flytende punktverdier.
  • noshowpos - Ikke sett inn plusstegn (+) hvis tallet> = 0.
  • showpos - Sett inn plusstegn (+) hvis tallet> = 0.
  • noskipws - Ikke hopp over hvitt mellomrom når du trekker ut.
  • skipws - Hopp over den første hvite plassen når du trekker ut.
  • nouppercase - Ikke bytt ut små bokstaver med store bokstaver.
  • store bokstaver - Erstatt små bokstaver med store bokstaver.
  • unitbuf - Spyl buffer etter et innlegg.
  • nounitbuf - Ikke skyll bufferen etter hvert innlegg.

04

av 08

Eksempler ved bruk av Cout

// ex2_2cpp. #inkludere "stdafx.h" #inkluderebruker navneområde std; int main (int argc, char * argv []) { kutebredde (10); cout << høyre << "Test" << endl; cout << venstre << "Test 2" << endl; cout << intern << "Test 3" << endl; cout << endl; cout.precision (2); cout << 45.678 << endl; cout << stor bokstav << "David" << endl; cout.precision (8); cout << vitenskapelig << endl; cout << 450678762345.123 << endl; cout << fast << endl; cout << 450678762345.123 << endl; cout << showbase << endl; cout << showpos << endl; cout << hex << endl; cout << 1234 << endl; cout << okt << endl; cout << 1234 << endl; cout << des << endl; cout << 1234 << endl; cout << noshowbase << endl; cout << noshowpos << endl; cout.unsetf (ios:: store bokstaver); cout << hex << endl; cout << 1234 << endl; cout << okt << endl; cout << 1234 << endl; cout << des << endl; cout << 1234 << endl; retur 0; }

Utgangen fra dette er under, med ett eller to ekstra linjerom fjernet for klarhet.

 Test. Test 2. Test 3. 46. David. 4.50678762E + 011. 450678762345.12299000. 0X4D2. 02322. +1234. 4D2. 2322. 1234. 

Merk: Til tross for store bokstaver, er David skrevet ut som David og ikke DAVID. Dette er fordi store bokstaver bare påvirker generert output - f.eks. tall trykt i heksadesimale. Så hex-utgang 4d2 er 4D2 når store bokstaver er i drift.

Dessuten setter de fleste av disse manipulatorene faktisk litt i et flagg, og det er mulig å sette dette direkte med

 cout.setf () 

og rydde det med

 cout.unsetf () 

05

av 08

Bruke Setf og Unsetf for å manipulere I / O-formatering

Funksjonen setf har to belastet versjoner vist nedenfor. Samtidig som unsetf bare tømmer de spesifiserte bitene.

 setf (flaggverdier); setf (flagvaluer, maskvalues); unsetf (flagvaluer); 

De variable flaggene er avledet av Oring sammen alle bitene du vil ha med |. Så hvis du vil vitenskapelige, store bokstaver og boolalpha bruk deretter dette. Bare bitene gikk inn som parameter er satt. De andre bitene er uendret.

 cout.setf (ios_base:: vitenskapelig | ios_base:: store bokstaver | ios_base:: boolalpha); cout << hex << endl; cout << 1234 << endl; cout << des << endl; cout << 123400003744.98765 << endl; bool verdi = true; cout << verdi << endl; cout.unsetf (ios_base:: boolalpha); cout << verdi << endl; 

produserer

 4D2. 1.234000E + 011. ekte. 1. 

Maskeringsbiter

De to parameter versjonen av setf bruker en maske. Hvis biten er satt i både den første og den andre parameteren, blir den satt. Hvis biten bare er i den andre parameteren, blir den tømt. Verdiene justeringsfelt, basefelt og floatfield (listet nedenfor) er sammensatte flagg, det vil si flere flagg ELLER-behandlet sammen. Til basefield med verdiene 0x0e00 er det samme som des | okt | hex. Så

 setf (ios_base:: hex, ios_basefield); 

tømmer alle tre flaggene og setter deretter hex. på samme måte adjustfield er venstre | rett | innvendig og floatfield er vitenskapelig | fikset.

Liste over biter

Denne listen over enums er hentet fra Microsoft Visual C ++ 6.0. De faktiske verdiene som er brukt er vilkårlige - en annen kompilator kan bruke forskjellige verdier.

 skipws = 0x0001. unitbuf = 0x0002. store bokstaver = 0x0004. showbase = 0x0008. utstillingspunkt = 0x0010. showpos = 0x0020. venstre = 0x0040. høyre = 0x0080. internt = 0x0100. dek = 0x0200. okt = 0x0400. hex = 0x0800. vitenskapelig = 0x1000. fast = 0x2000. boolalpha = 0x4000. justeringsfelt = 0x01c0. basefelt = 0x0e00, floatfield = 0x3000. _Fmtmask = 0x7fff, _Fmtzero = 0. 

06

av 08

Om Clog og Cerr

Som domstol, tresko og cerr er forhåndsdefinerte objekter definert i ostream. Istream-klassen arver fra begge ostream og istream så det er derfor domstol eksempler kan bruke iostream.

Bufret og ubufret

  • Bufret - All utgang lagres midlertidig i a buffer og deretter dumpet til skjerm på en gang. Både cout og tette er bufret.
  • Unbuffered - All output går umiddelbart til output-enheten. Et eksempel på et ubuffet objekt er cerr.

Eksemplet nedenfor viser at cerr brukes på samme måte som cout.


#inkludere bruker navneområde std; int _tmain (int argc, _TCHAR * argv []) {cerr. bredde (15); cerr.right; cerr << "Feil" << endl; retur 0; }

Hovedproblemet med bufring er hvis program krasjer så går buffertinnholdet tapt, og det er vanskeligere å se hvorfor det krasjet. Ubufret utgang er øyeblikkelig, så det kan være nyttig å sprite noen få linjer som denne gjennom koden.

 cerr << "Entering Dangerous function zappit" << endl; 

Loggproblemet

Å bygge en logg over programhendelser kan være en nyttig måte å oppdage vanskelige feil - den typen som bare forekommer nå og da. Hvis den hendelsen imidlertid er et krasj, har du problemet - spoler du loggen til disken etter hver samtale slik at du kan se hendelser helt frem til krasjet eller hold den i en buffer og skyll bufferen med jevne mellomrom og håper du ikke mister for mye når krasjet inntreffer?

07

av 08

Bruke Cin for inndata: formatert inndata

Det er to typer innspill.

  • Formatert. Lesing av innspill som tall eller av en viss type.
  • Uformatert. Lese byte eller strenger. Dette gir mye større kontroll over innsatsstrømmen.

Her er et enkelt eksempel på formatert input.

 // excin_1.cpp: Definerer inngangspunktet for konsollprogrammet. #include "stdafx.h" // Microsoft bare. #inkludere bruker navneområde std; int main (int argc, char * argv []) { int a = 0; flyte b = 0,0; int c = 0; cout << "Skriv inn et int, en flyter og int atskilt med mellomrom" <> a >> b >> c; cout << "Du skrev inn" << a << "" << b << "" << c << endl; retur 0; }

Denne bruker cin for å lese tre tall (int, flyte, int) atskilt av mellomrom. Du må trykke enter når du har skrevet inn nummeret.

3 7.2 3 vil gi ut "Du skrev inn 3 7.2 3".

Formaterte innspill har begrensninger!

Hvis du oppgir 3.76 5 8, får du "Du skrev inn 3 0,76 5", alle andre verdier på den linjen går tapt. Det oppfører seg riktig, som. er ikke en del av intet og markerer så starten på flottøren.

Feil feller

Cin-objektet angir en feilbit hvis inngangen ikke ble konvertert. Denne biten er en del av ios og kan leses ved bruk av Fail () funksjon på begge cin og domstol som dette.

 hvis (cin.fail ()) // gjør noe. 

Ikke overraskende, cout.fail () settes sjelden, i det minste på skjermutgang. I en senere leksjon om fil I / O, får vi se hvordan cout.fail () kan bli sant. Det er også en god() funksjon for cin, domstol etc.