Sie sind auf Seite 1von 33

CSCE 121:509-512

Introduction to Program Design and


Concepts
Dr. J. Michael Moore
Spring Fall 2016
Set 10: Input/Output Streams

CSCE 121:509-512

1
Based on slides created by
Stroustrup
SetBjarne
10: Input/Output
Streams and Jennifer Welch

Outline
Fundamental I/O concepts
Files
opening and closing
reading and writing streams

I/O errors
Reading a single integer
User-defined I/O
CSCE 121:509-512
Set 10: Input/Output Streams

Input and Output


data source:
input device

device driver

input library

our
ourprogram
program

output library

device driver

CSCE 121:509-512
Set 10: Input/Output Streams

data
destination:
output device

The Stream Model

somewhere
(1,234)

ostream

123

buffer

An ostream
turns values of various types into character
sequences
sends those characters somewhere (console,
file, main memory, another computer)
CSCE 121:509-512
Set 10: Input/Output Streams

The Stream Model

somewhere
(1,234)

123

istream

buffer

An istream
turns character sequences into values of
various types
gets those characters from somewhere
(console, file,CSCE
main
memory, another
121:509-512
5
Set 10: Input/Output Streams
computer,)

The Stream Model


Supports reading and writing
of typed entitites
<< (output) and >> (input) plus other
operations
type-safe
formatted

typically stored as text


but not necessarily, e.g, binary streams

extensible
define your own I/O operations for your own
types

a stream canCSCE
be121:509-512
attached to any I/O or
6
Set 10: Input/Output Streams
storage device

Files
Main memory is transient
when power goes off, contents of main
memory is lost

Use disks, etc. for permanent storage


A file is a sequence of bytes in
permanent storage
a file has a name
the data in a file has a format

We can read and write a file if we


know its name and format
CSCE 121:509-512
Set 10: Input/Output Streams

Files
General model

disk

I/O system

iostreams

Files
(sequences of bytes)

CSCE 121:509-512
Set 10: Input/Output Streams

main memory

Objects
(of various types)

Reading a File
1.
2.
3.
4.

Obtain the files name


Open the file for reading
Read from the file
Close the file
usually done implicitly

. Uses a special kind of istream called


an ifstream
CSCE 121:509-512
Set 10: Input/Output Streams

Writing a File
1. Name the file
2. Open the file for writing
either an existing file or create a new
one

3. Write to the file


4. Close the file
usually done implicitly

. Uses a special kind of ostream called


an ofstream
CSCE 121:509-512
Set 10: Input/Output Streams

10

Opening a File for Reading


cout<<Enterinputfilename:;
stringiname;
cin>>iname;
ifstreamist{iname};//oriname.c_str()
//istisavariableoftypeifstream;notespecial
//constructorsyntaxwith{and}.
if(!ist)error(Cantopeninputfile,iname);
//ifnoerror,thenvariableistisultimately
//connectedtothefilewhosenameis
//storedinthevariableiname
intx;
ist>>x;//readfromistusing>>(aswithcin)
CSCE 121:509-512
Set 10: Input/Output Streams

11

Opening a File for Writing


cout<<Enterinpoutfilename:;
stringoname;
cin>>oname;
ofstreamost{oname};//oroname.c_str()
//ostisavariableoftypeofstream;notespecial
//constructorsyntaxwith{and}.
if(!ost)error(Cantopenoutputfile,oname);
//ifnoerror,thenvariableostisultimately
//connectedtothefilewhosenameis
//storedinthevariableoname
intx=67;
ost<<x;//writetoostusing<<(aswithcout)
CSCE 121:509-512
Set 10: Input/Output Streams

12

Opening and Closing Files


File is automatically opened when
ifstream or ofstream variable is
created
File is automatically closed when
ifstream or ofstream variable goes
out of scope
for example, the function in which the
variable is declared returns

In rare circumstances, you might


need to explicitly open or close a file
at other times
CSCE 121:509-512
Set 10: Input/Output Streams

13

File I/O Example


Suppose we are given a file
containing temperature data in the
format
060.7
160.6
260.3

where first number per line is hour of


the day (0 through 23) and second
number per line is temperature (in
Fahrenheit).
Task is to reformat the file to be this:
(0,60.7)

CSCE 121:509-512
Set 10: Input/Output Streams

14

File I/O Example: Design


Use a struct that puts together the
hour number and its matching
temperature:
structReading{
inthour
doubletemperature;
};

Successively obtain readings from


input file and store in a vector of
Readings
Loop through the vector and write
CSCE 121:509-512
Set 10: Input/Output Streams

15

File I/O Example Details


//assumingpreviouscodeforopeningfilesandReadingstruct
vector<Reading>temps;
inthour;
doubletemperature;
while(ist>>hour>>temperature){
if(hour<0||23<hour)error(houroutofrange);
temps.push_back(Reading{hour,temperature});
}
for(Readingr:temps){
ost<<(<<r.hour<<,<<r.temperature<<)\n;
}
//Seepage354oftextbookforcompletecode

CSCE 121:509-512
Set 10: Input/Output Streams

16

I/O Error Handling


iostream

reduces all errors to one of four

states:

good()//theoperationsucceeded
eof()//wehittheendoftheinput
fail()//somethingunexpectedhappened
bad()//somethingunexpectedandserioushappened

These 4 are functions that return true under


the stated conditions, otherwise false
Conditions are indicated by certain bits being
set
Clear all the bits and return to the good() state
with the function
CSCE 121:509-512
17

clear()

Set 10: Input/Output Streams

I/O Error Handling and


Conditions

We have been using these C++


idioms:

while(cin>>var)/*whileloopbody*/
if(!ist)/*reporterror*/

What is going on?


Extraction (>>) and insertion (<<)
operators on streams return references
to the stream
There is an implicit conversion from a
stream object to a boolean (e.g., in the
conditions of while and if statements)
The conversion
yields true if the
stream
CSCE 121:509-512
18
Set 10: Input/Output Streams

Sample Integer Read


Failures

Ended by terminator character


12345*
state is fail()

Ended by format error


1 2 3 4 5.6
state is fail()

Ended by end of file

123
123
123
state

4 5 (no more data in file)


4 5 Ctrl-Z (Windows)
4 5 Ctrl-D (Unix)
is eof()

Something really bad


disk format error
state is bad()

CSCE 121:509-512
Set 10: Input/Output Streams

19

I/O Error Handling with Stream


States
voidfill_vector(istream&ist,vector<int>&v,charterminator)
//readintegersfromistintovuntilreachingeof()orterminator
{
inti=0;
while(ist>>i)v.push_back(i);
if(ist.eof())return;//fine:wefoundendoffile
if(ist.bad())error(istisbad);//streamcorrupted,getout
if(ist.fail()){//trytocleanup,maybewefoundterminator
ist.clear();//clearstreamstatesowecanlookforterminator
charc;
ist>>c;//trytoreadachar
if(c!=terminator){//unexpectedchar(notterminator)
ist.unget();//putcharacterbackintostream
ist.clear(ios_base::failbit);//setstatebacktofail()
}
}
}

CSCE 121:509-512
Set 10: Input/Output Streams

20

Throw an Exception for bad()


Simplify previous logic by not even
worrying about bad() just throw an
exception
After defining ifstreamist, indicate
that you want an exception thrown if
its state ever goes bad():
ist.exceptions(ist.exceptions()|ios_base::badbit);

This will cause an exception of type


ifstream::failureto be thrown, which
you can catch where you like
CSCE 121:509-512
Set 10: Input/Output Streams

21

Another Example: Reading


an Integer in a Range
Problem statement: Read in an
integer within some range (say, 1 to
10)
Deal with
user enters an integer not in range
user enters something of wrong type
user enters nothing

Need appropriate prompts to the


user
See Section 10.7 of textbook for bad
CSCE 121:509-512
Set 10: Input/Output Streams

22

Reading an Integer in Range


Key to having a clean solution to the
problem is to break things into logically
separate manageable pieces:
1.
2.
3.
4.
5.

reading values
prompting user for input
writing error messages
skipping past bad input characters
testing the input against a range

Also aim for generality


. dont hardcode range bounds
. dont hardcode prompts
CSCE 121:509-512
Set 10: Input/Output Streams

23

Reading an Integer in a
Range
intget_int(intlow,inthigh,
conststring&greeting,
conststring&sorry)
{
cout<<greeting<<between<<low<<and
<<high<<endl;
while(true){
intn=get_int();
if(low<=n&&n<=high)returnn;//success
cout<<sorry<<endl;
}
}

CSCE 121:509-512
Set 10: Input/Output Streams

24

Reading an Integer
intget_int()
{
intn=0;
while(true){
if(cin>>n)returnn;//success
cout<<Notanumber,tryagain\n;
skip_to_int();
}
}

CSCE 121:509-512
Set 10: Input/Output Streams

25

Skipping Bad (non-int)


Characters

voidskip_to_int()
//precondition:ciniseitherfail()oreof()
{
if(cin.fail(){//foundsomething,butnotanint
cin.clear();//wewanttolookatthecharacters
//whydoesthisforloopnotneedtoincrement?
for(charch;cin>>ch;){
if(isdigit(ch)||ch==){
cin.unget();//putdigitbacksowecanreadint
return;
//ifnotadigitorthenignoreitandcontinue
}
}
//onlyremainingoptioniseof()
error(noinput);
}
CSCE 121:509-512
Set 10: Input/Output Streams

26

Reading an Int in Range:


Remaining Issues
Error message in get_int()is not
parameterized
Ideally, utility functions should not
have messages hardcoded into them
In fact, library functions shouldnt
(directly) write to the user at all
instead throw exceptions, which can
contain error messages
CSCE 121:509-512
Set 10: Input/Output Streams

27

User-Defined Output:
operator<<()
Must return a reference to an
ostream
First parameter must be a reference
to an ostream
Second parameter must be a
reference to an object of your type
ostream&operator<<(ostream&os,constDate&d)
{
returnos<<(<<d.year()<<,<<d.month()
<<,<<d.day()<<);
CSCE 121:509-512
28
}
Set 10: Input/Output Streams

Calling User-Defined <<


voidprint_out(Dated1,Dated2)
{
cout<<d1;
//meansoperator<<(cout,d1);
cout<<d1<<d2;
//means(cout<<d1)<<d2;
//means(operator<<(cout,d1))<<d2;
//means(operator<<((operator<<(cout,d1)),d2);
}

CSCE 121:509-512
Set 10: Input/Output Streams

29

User-Defined Input:
operator>>()
Must return a reference to an istream
First parameter must be a reference
to an istream
Second parameter must be a
reference to an object of your type

CSCE 121:509-512
Set 10: Input/Output Streams

30

operator>>() Example
istream&operator>>(istream&is,Date&dd)
//Assumedateisinformat(year,month,day)
{
inty,d,m;
charch1,ch2,ch3,ch4;
is>>ch1>>y>>ch2>>m>>ch3>>d>>ch4;
if(!is)returnis;//wedidntgetourvalues;leave
if(ch1!=(||ch2!=,||ch3!=,
||ch4!=)){
//oops:formaterror
is.clear(ios_base::failbit);//setstreamstatetofail
returnis;//leave
}
dd=Date(y,Month(m),d);//updateddviacopyassignment
returnis;//leavewithisingoodstate
}
CSCE 121:509-512
Set 10: Input/Output Streams

31

Calling User-Defined >>


//...
cout<<Enteradateinformat(year,month,date):;
Dated;
cin>>d;
if(cin)//continue...

CSCE 121:509-512
Set 10: Input/Output Streams

32

Acknowledgments
Slides are based on those for the
textbook:
http://www.stroustrup.com/Programming/10_iostr
eams.ppt

CSCE 121:509-512
Set 10: Input/Output Streams

33

Das könnte Ihnen auch gefallen