Introduction to C Programming Module 5 C Stream I/O and Exception Handling - PowerPoint PPT Presentation

About This Presentation
Title:

Introduction to C Programming Module 5 C Stream I/O and Exception Handling

Description:

... the throw statement are ignored and the try-block exits (the stack is unwound. ... Stack Unwinding ... unwound, the local objects at each unwound level ... – PowerPoint PPT presentation

Number of Views:33
Avg rating:3.0/5.0
Slides: 33
Provided by: yaodo
Category:

less

Transcript and Presenter's Notes

Title: Introduction to C Programming Module 5 C Stream I/O and Exception Handling


1
Introduction to C ProgrammingModule 5 C
Stream I/O and Exception Handling
  • Yaodong Bi, Ph.D.
  • Department of Computing Sciences
  • University of Scranton
  • (717)941-6108
  • bi_at_cs.uofs.edu

2
Outline
  • Module 1 - An Overview of C and OO Programming
  • Module 2 - Classes and Operator Overloading
  • Module 3 - Inheritance and Dynamic Binding
  • Module 4 - Function and Class Templates
  • Module 5 - C Stream I/O and Exception Handling

3
Review of Module 4
  • Function Templates
  • Function Template Definition
  • Function Template Instantiation
  • Template Explicit Specialization
  • Overloading Function Templates
  • Template Compilation Models
  • Class Templates
  • Class Template Definition
  • Class Template Instantiation
  • Members of Class Templates
  • Friend Declarations in Class Templates
  • Class Template Compilation Model

4
Outline of Module 5
  • Exception Handling
  • Throwing an Exception and the Try Block
  • Catching an Exception
  • Exception Specifications
  • Advanced Topics
  • C Stream I/O
  • Input/Output of Built-in Types
  • Formats
  • Overloading the I/O Operators ltlt and gtgt
  • File Input and Output
  • Condition States

5
Example 1 Stack with Exceptions
  • // except.cpp
  • include "except.h"
  • CPopOnEmptyCPopOnEmpty(int sz)
  • m_nStackSize(sz)
  • void CPopOnEmptyPrint() const
  • cout ltlt "Exception Pop on empty stack!\n"
  • cout ltlt "Stack Size " ltlt m_nStackSize ltlt endl
  • CPushOnFullCPushOnFull(int sz)
  • m_nStackSize(sz)
  • void CPushOnFullPrint() const
  • cout ltlt "Exception Push on Full stack!\n"
  • // except.h
  • include ltiostream.hgt
  • class CPopOnEmpty
  • public
  • CPopOnEmpty(int sz 0)
  • void Print() const
  • private
  • int m_nStackSize
  • class CPushOnFull
  • public
  • CPushOnFull(int sz 0)
  • void Print() const
  • private

6
Ex 1 Stack with Exceptions - contd
  • // stack.cpp
  • include ltiostream.hgt
  • include "Stack.h"
  • include "except.h"
  • void CStackPush(int item)
  • if (IsFull()) throw CPushOnFull(m_nSize)
  • m_Arraym_nTop item
  • int CStackPop()
  • if (IsEmpty()) throw CPopOnEmpty(m_nSize)
  • return m_Arraym_nTop--
  • bool CStackIsEmpty() const
  • return (m_nTop lt 0)
  • bool CStackIsFull() const
  • return (m_nTop m_nSize - 1)
  • // Stack.h
  • const int maxSize 10
  • class CStack
  • public
  • CStack(int sz maxSize)
  • CStack(const CStack)
  • CStack operator
  • (const CStack)
  • void Push (int item)
  • int Pop()
  • bool IsEmpty() const
  • bool IsFull() const
  • CStack()
  • private
  • int m_Array
  • int m_nTop

7
Ex 1 Stack with Exceptions - contd
  • // stack.cpp -- contd
  • CStackCStack(int sz)
  • m_Array new intsz
  • m_nSize sz
  • m_nTop -1
  • CStackCStack(const CStack stack)
  • m_nSize stack.m_nSize
  • m_nTop stack.m_nTop
  • m_Array new intm_nSize
  • for (int i0 iltm_nTop i)
  • m_Arrayi stack.m_Arrayi
  • CStack
  • CStackoperator(const CStack stack)
  • if (stack ! this)
  • delete m_Array
  • m_nSize stack.m_nSize
  • m_nTop stack.m_nTop
  • m_Array new intm_nSize
  • for (int i0 iltm_nTop i)
    m_Arrayi stack.m_Arrayi
  • // class.cpp
  • include ltiostream.hgt
  • include "Stack.h"
  • include "except.h"
  • void main()
  • CStack stack
  • try
  • for ( int i 1 i lt maxSize3 i)
  • stack.Push(i100)
  • catch (CPushOnFull pushExcept)
  • pushExcept.Print()

8
Ex 1 Stack with Exceptions - contd
  • // class.cpp -- contd
  • try
  • for ()
  • cout ltlt stack.Pop() ltlt endl
  • catch (CPopOnEmpty popExcept)
  • popExcept.Print()
  • The first for-loop tries to push three more items
    than the capacity of the stack.
  • The second infinite for-loop pops until the stack
    is empty
  • Exception objects
  • class CPopOnEmpty
  • class CPushOnFull
  • The throw expression
  • void CStackPush(int item)
  • if (IsFull()) throw CPushOnFull(m_nSize)
  • .
  • The try - catch block
  • try
  • for ()
  • cout ltlt stack.Pop() ltlt endl
  • catch (CPopOnEmpty popExcept)
  • popExcept.Print()

9
Exception Handling
  • Problem Statement
  • The designer of a library can detect run-time
    errors, but does not in general know what to do
    with them. The user of the library may know how
    to cope with such errors but cannot detect them.
  • Ex. The user of a math library may not know when
    a expression may have a divide-by-zero operation.
    The math library can detect it and the user
    program may know how to handle it.
  • A Solution -- Exception handling
  • Exceptions provide a way for code that detects a
    problem from which it cannot recover to pass the
    problem on to some part of the system that might
    be able to recover.
  • C implementation on Exception handing
  • A function that finds a problem it cannot handle
    throws an exception, and its (direct or indirect)
    caller that can handle the problem catches the
    exception.
  • Ex. The math library throws a divide-by-zero
    exception, the user program catches the exception
    and handles it.

10
Throwing an Exception and the Try Block
  • Throwing an Exception -- by the detector
  • Syntax throw An_Exception
  • ex throw 2
  • throw CPopOnEmpty(m_nSize) // call a
    constructor
  • An exception must be an object it cannot be a
    class type.
  • throw CPopOnEmpty // illegal - not an object
  • The Try Block -- by the caller
  • The caller that can handle the exception executes
    the try block.
  • try
  • // statements that can cause exceptions
  • catch (Exception_1)
  • // handle exception1
  • .
  • catch (Exception_n)
  • // handler exception_n

11
Throwing an Exception and the Try Block
  • Control flow of the try block
  • If no exception occurs, the code in the try-block
    is executed and its handlers are ignored. The
    next statement after the last catch clause is
    executed.
  • If an exception is thrown,
  • the statements following the throw statement are
    ignored and the try-block exits (the stack is
    unwound.).
  • The catch clauses are checked in order. The first
    matched catch is executed. After a catch clause
    is completed, the program continues at the
    statement following the last catch in the list.
  • If no catch clause can catch the exception, the
    exception is passed to the next caller along the
    calling chain.
  • Once an exception is thrown, the program does not
    resume where the exception was originally thrown
    even after the exception is handled.
  • A try block introduces a local scope -- a
    variable declared within the block cannot be
    referred to outside the block, including the
    catch clauses.
  • try int x
  • catch (exception) cout ltlt x // error x is
    undefined
  • It is possible to include the entire body of a
    function in the try block.
  • int main()
  • try // the body of main() catch (exception)

12
Catching an Exception
  • Exception objects
  • The exception declaration of a catch clause can
    be either a type declaration or an object
    declaration.
  • try catch (int) // type delcaration.
  • try catch (int x) cout ltlt x ... //
    object delcaration.
  • try catch (CPopOnEmpty x) x.Print()
    ... // object delcaration.
  • An exception object is always created at the
    throw point.
  • Type X // a global variable
  • int main ()
  • try ...throw X
  • // an exception object is created and
    initialized with X
  • catch (Type EX) EX Y
  • // EX is copied from the exception object.
    The assignment // changes the local EX, not
    the exception object, not the global X
  • catch (Type EX) EX Y
  • // EX is a reference to the exception
    object, not the global X
  • // the assignment changes the exception
    object

13
Catching an Exception
  • Stack Unwinding
  • When an exception cannot be handled, the search
    is continued to the calling function. This is
    continued until the exception can be handled or
    the program terminates.
  • Ex try foo(x) void foo(x) void
    foobar()
  • catch (Type1) try foobar()
    .
  • //handler Type1 catch (Type2) throw
    Type1()
  • .
  • As the stack being unwound, the local objects at
    each unwound level end and their destructors are
    called.
  • In the above example, when throw Type() is
    completed,
  • 1. all local variables in foobar() are destroyed
    with their destructors.
  • 2. All local variables in foo() are destroyed
    with their destructors.
  • The Catch-all handler -- ellipsis.
  • Ex try // should be used as the last catch
    clause.
  • catch () // enter for any type of exception

14
Catching an Exception
  • Rethrow
  • A catch clause can pass the exception further up
    the list of function calls by re-throwing the
    exception.
  • Ex try foo(x)
  • catch (Type1 EX)
  • if (cannothandle(EX)) throw //
    re-throw the exception
  • .
  • The exception that is re-thrown is the original
    exception object.
  • Type X // a global variable
  • int foo ()
  • try ...throw X catch (Type EX) EX
    y throw
  • int main ()
  • try foo()
  • catch (Type EX1) EX1 z
  • // EX1 references to the original except. object
    copied from the global X
  • // it doesnt reference to EX in foo(), not to
    the global X either.

15
Exception Specifications
  • An exception specification follows the function
    parameter list.
  • class CStack
  • ...
  • void Push (int item) throw (CPushOnFull)
  • int Pop() throw (CPushOnFull)
  • An empty exception specification guarantees that
    the function doesnt throw any exception.
  • void foo(int item) throw () // foo() will not
    throw any exception
  • If a function declaration does not specify an
    exception specification, it may throw exceptions
    of any type.
  • void foo(int item) // foo() can throw an
    exception of any type
  • If a function throws an exception that is not in
    the specification list, the function unexpected()
    in the standard library is invoked, which in
    turn, by default, terminates the program.
  • MS VC 6.0 doesnt seem to support exception
    specifications.

16
Advanced Topics Grouping of Exceptions
  • Grouping of Exceptions Put exceptions into
    families

class Matherr // virtual void
debug_print() class Overflow public Matherr
// virtual void debug_print() class
ZeroDivide public Matherr // virtual void
debug_print() class IntOverflow public
Overflow // virtual void debug_print()
int add(int x, int y) // .. if (overflow())
throw IntOverflow() void foo() try
int i add(INT_MAX, 2) catch (Matherr
m) m.debug_print() // IntOverflows
debug_print()
17
Advanced Topics Resource Management
  • Resource Acquisition is initialization

class File_ptr FILE p public File_ptr(const
char n, const char a) p fopen(n, a)
File_ptr() fclose(p) void
use_file(const char fn) File_ptr f_ptr(fn,
r) // use file f_ptr is a local object of
use_file(). If an exception occurs in
use_file(), the file pointed by f_ptr would be
closed when use_file exits and File_ptrs
destructor is called automatically.
class Acquire File_ptr ff Lock_ptr
ll public Acquire(const char n, const char
m) ff(n, r), // acquire ff ll(m)
//acquire ll // constructor body If an
exception occurs in ll(m), the destructor of ff
will be invoked. If the Acquire constructors
body has an exception, the destructors of ff and
ll will be invoked. gt resources are released.
18
Input/Output of Built-in Types
  • Input/Output classes
  • istream input stream class
  • ostream output stream class
  • iostream bidirectional input/output class
  • Standard Input/Output objects
  • cin an istream class object for standard input
  • cout an ostream class object for standard output
  • cerr an ostream class object for standard error
    output
  • The output operator ltlt.
  • It accepts argument of any of the built-in data
    types.
  • cout ltlt int_var ltlt double_var
  • cout ltlt this is a string!\n ltlt char_ptr
  • cout ltlt int_var // print the address
    of int_var in hexadecimal.
  • cout ltlt true ltlt false // print 1 and 0
    respectively, by default.
  • Operator ltlt associates left to right
  • cout ltlt x ltlt y // is equivalent to
  • ( cout ltlt x ) ltlt y

19
Input/Output of Built-in Types
  • The input operator gtgt.
  • It accepts argument of any of the built-in data
    types.
  • cin gtgt int_var gtgt double_var
  • cin ltlt char_var // all white spaces are
    skipped
  • Operator gtgt associates left to right
  • cin gtgt x gtgt y // is equivalent to
  • ( cin gtgt x ) gtgt y
  • By default, the operator gtgt discards any
    intervening white space ( blank, tab, newline,
    formfeed, and carriage return).
  • Input sequence 123 1
  • b c d
  • cin gtgt int_var gtgt ch1 gtgtch2 gtgt ch3 gtgtch4
  • cout ltlt int_varltltch1ltltch2ltltch3ltltch4
  • // prints 1231bcd
  • To process every input character including white
    spaces
  • while (cin.get(char_var)) cout.put(char_var)
  • // read every char in input and print char by
    char

20
Formats
  • Integer outputs
  • cout.setf(ios_baseoct, ios_basebasefield)
  • cout ltlt 1234 //print octal 2322
  • cout.setf(ios_basedec, ios_basebasefield)
  • cout ltlt 1234 //print decimal 1234 -- decimal is
    the default
  • Floating-point output
  • cout ltlt 1234.56789 // default output 1234.57
  • cout.setf(ios_basescientific,
    ios_basefloatfield)
  • cout ltlt 1234.56789 // scientific format
    1.2345678e003
  • cout.setf(ios_basefixed, ios_basefloatfield)
  • cout ltlt 1234.56789 // fixed point format
    1234.567890
  • cout.setf(0, ios_basefloatfield) // reset
    default
  • cout.precision(8) // set precision to 8
  • cout ltlt 1234.56789 // print 1234.5679
  • Above print results were generated with MS VC
    6.0 and its standard iostream.

21
Formats
  • Output fields
  • cout.width(4) // only affect the immediate ltlt
    operation
  • cout ltlt 12 //print with two space in front of
    12
  • cout.width(4) cout.fill()
  • cout ltlt 12 //print 12
  • cout.width(0) // print as many as needed
  • Field adjustment
  • cout.width(4) cout.fill()
  • cout.setf(ios_baseleft, ios_baseadjustfield)
    // left
  • cout.width(4) cout ltlt -12 // print -12
  • cout.setf(ios_baseright, ios_baseadjustfield)
    // right -- default
  • cout.width(4) cout ltlt 12 // print 12
  • cout.setf(ios_baseinternal, ios_baseadjustfiel
    d) // between sign and
  • cout.width(4) cout ltlt -12 // print -12
  • Above print results were generated with MS VC
    6.0 and its standard iostream.

22
Formats
  • Manipulators -- must include ltiomanipgt
  • cout ltlt x ltlt flush ltlt y ltlt flush
  • // explicitly request that the buffer be
    flushed.
  • cin gtgt noskipws gtgt x
  • // dont skip white spaces.
  • cout ltlt 1234 ltlt , ltlthexltlt 1234 ltlt, ltlt oct
    ltlt 1234
  • // prints 1234, 4d2, 2322.
  • cout ltlt setw(6) ltlt setfill() ltlt 12
  • // prints 12.
  • When using manipulators that dont take
    arguments, dont add ().
  • cout ltlt hex() ltlt 12 // error hex doesnt take
    arguments
  • make sure include ltiomanipgt in your program
  • Users may define their own manipulators
  • The manipulators shown here are only some
    examples. For more comprehensive descriptions,
    read Lippmans and Strousptrups books.
  • Above print results were generated with MS VC
    6.0 and its standard iostream.

23
Overloading the I/O operators ltlt and gtgt
  • General skeleton of an overloaded output operator
  • ostream operatorltlt(ostream os, const ClassType
    obj)
  • // actual output of the members.
  • os ltlt //
  • // return ostream object
  • return os
  • General skeleton of an overloaded input operator
  • istream operatorgtgt(istream is, ClassType obj)
  • // actual input to the members.
  • os gtgt //
  • // return istream object
  • return is

24
Overloading the I/O operators ltlt and gtgt
  • An Example
  • class complex
  • friend ostream operatorltlt(ostream os, const
    complex obj)
  • friend istream operatorgtgt(istream is, complex
    obj)
  • Private
  • int real, image
  • ostream operatorltlt(ostream os, const complex
    obj)
  • os ltlt lt ltltobj.real ltlt, ltltobj.imageltlt
    gt\n
  • return os
  • istream operatorgtgt(istream is, complex obj)
  • is gtgt obj.real gtgt obj.image
  • return is
  • int main()
  • complex cmplx
  • cin gtgt cmplx
  • cout ltlt cmplx

25
Overloading the I/O operators ltlt and gtgt
  • Virtual output functions
  • The ostream members are not virtual.
  • Since the exact type of a subclass may not be
    known yet, correct output cannot be achieved
    simply by defining a ltlt for each new type.
  • Implementation
  • Design a virtual put function in the base and
    subclasses.
  • virtual ostream put(ostream s)
  • Call the virtual function in ltlt from a reference
    to the base
  • ostream operatorltlt
  • (ostream s, base b)
  • return b.put(s)
  • ltlt doesnt need to be a friend of the classes in
    this example.
  • include "stdafx.h"
  • include ltiostream.hgt
  • class base
  • public
  • virtual ostream put(ostream s)
  • return s ltlt"Base\n"
  • class derived public base
  • public
  • virtual ostream put(ostream s)
  • return s ltlt"Derived\n"
  • ostream operatorltlt(ostream s, base b)
  • return b.put(s)
  • int main(int argc, char argv)
  • base bs derived dr
  • cout ltlt bs ltlt dr

26
File Input and Output
  • To use file input and output, include
  • include ltfstreamgt
  • using namespace std
  • To open a file for output only.
  • ofstream outfile(filename, ios_baseout)
  • ofstream outfile(filename) // output is
    default
  • // when the file does not exist, it would be
    created.
  • // if an file is opened for output, all data in
    the file is discarded.
  • if (!outfile) //open failed.
  • cerr ltlt file cannot be opened!\n
  • exit(-1)
  • ofstream is derived from ostream. All the ostream
    operations can be applied to ofstream objects.
  • char ch
  • outfile.put(1).put()).put(ch)
  • outfileltlt11 ltlt 11 ltlt endl
  • // insert 1) 11 2 to outfile.
  • To open a file for append.
  • ofstream outfile(filename, ios_baseapp)

27
File Input and Output
  • To open a file for input only.
  • ifstream infile(filename)
  • if (!infile)
  • cerr ltltinput file open failed\n
  • exit(-1)
  • infile gtgt int_var
  • while (infile.get(ch)) cout.put(ch)
  • An fstream object can open a file for either
    input and output.
  • fstream file
  • file.open(filename, ios_basein) // open the
    file for input
  • file gtgt wd
  • file.close()
  • file.open(filename, ios_baseapp) // open the
    same file for output
  • file ltlt endl ltlt wd ltlt endl
  • file.close()
  • An fstream object can open a file for both input
    and output.
  • fstream file

28
Condition States
  • Condition flags.
  • eof() return true if end-of-file has been
    encountered.
  • if (cin.eof() ) // ok, input complete.
  • bad() return true if an invalid op. has been
    attemped -- file corrupted.
  • if (cin.bad() ) // file corrupted in some
    undefined way.
  • fail() return true if an o.p has been
    unsuccessful. Ex. Invalid input format
  • ifstream infile(filename)
  • if (infile.fail() ) // file open failed.
  • good() return true if previous operation was
    successful - file in good cond.
  • If (infile.good() ) // continuing processing
    the file.
  • Two methods for modifying the condition states.
  • clear() resets the condition state to an explicit
    value
  • cin.clear(ios_basegoodbit) // reset cin to
    good condition
  • setstate() add a condition tot he existing
    condition of the object.
  • if ((ch is.get()) ! lt) cin.setstate(ios_bas
    efailbit)
  • // if the current char is not lt, mark the
    fail state.
  • To set multiple states,
  • cin.setstate(ios_basebadbit
    ios_basefailbit)
  • // set both bad state and fail state.

29
Summary of Module 5
  • Exception Handling
  • Throwing an Exception and the Try Block
  • Catching an Exception
  • Exception Specifications
  • Advanced Topics
  • C Stream I/O
  • Input/Output of Built-in Types
  • Formats
  • Overloading the I/O Operators ltlt and gtgt
  • File Input and Output
  • Condition States

30
Advice
  • Dont use exceptions where more local control
    structures will suffice.
  • Use the resource acquisition is initialization
    to manager resources.
  • Not every program needs to be exception safe.
  • Avoid throwing exceptions from copy constructors.
  • Avoid throwing exceptions from destructors.
  • Throw an exception to indicate failure in a
    constructor.
  • Develop an error-handling strategy early in the
    design.
  • Overload ltlt and gtgt for user-defined types with
    values that have meaningful textual
    representations.
  • Remember that by default gtgt skips white spaces
  • Remember to include ltiomanipgt when using
    standard manipulators.
  • Remember that the width manipulator applies to
    the following I/O operation only.
  • Define virtual input/output functions.

31
Programming Assignments
  • Exception -- CDate
  • Modify the CDate example so that it throws
    exceptions when a value is out of valid range.
  • Group the exceptions in CDate into a class
    hierarchy. Use virtual functions to print
    offensive values (year, month, or day).
  • Write a main() to test those exceptions.
  • Exception -- An array class
  • Design an array class that throws OutOfRange when
    the subscript is of range. OutOfRange can print
    the size of the array and the offensive
    subscript.
  • Overload Operators ltlt and gtgt
  • Design virtual input and output functions for the
    CPerson-CManager-CEngineer inheritance example.
  • File Input/output
  • Design a program that counts the number of words
    and the number of white spaces in the input file.

32
(No Transcript)
Write a Comment
User Comments (0)
About PowerShow.com