void FloatArr::insertfloat val, int pos throwBadIndex { insert FloatArr1, val, pos; } void FloatArr::insert const FloatArr& v, int pos throw BadIndex { if pos < 0 || pos > cnt // Appen
Trang 1float& FloatArr::operator[]( int i ) throw(BadIndex)
{
if( i < 0 || i >= cnt ) throw BadIndex(i);
return arrPtr[i];
}
float FloatArr::operator[]( int i ) const throw(BadIndex)
{
if( i < 0 || i >= cnt ) throw BadIndex(i);
return arrPtr[i];
}
// Append a float value or an array of floats
void FloatArr::append( float val)
{
if( cnt+1 > max)
expand( cnt+1);
arrPtr[cnt++] = val;
}
void FloatArr::append( const FloatArr& v)
{
if( cnt + v.cnt > max)
expand( cnt + v.cnt);
int count = v.cnt; // Necessary if
// v == *this
for( int i=0; i < count; ++i)
arrPtr[cnt++] = v.arrPtr[i];
}
// Inserts a float value or an array of floats
void FloatArr::insert(float val, int pos) throw(BadIndex)
{
insert( FloatArr(1, val), pos);
}
void FloatArr::insert( const FloatArr& v, int pos )
throw( BadIndex ) {
if( pos < 0 || pos > cnt) // Append is also possible throw BadIndex(pos);
if( max < cnt + v.cnt)
expand(cnt + v.cnt);
int i;
for( i = cnt-1; i >= pos; i) // Shift up from
arrPtr[i+v.cnt] = arrPtr[i]; // position pos
for( i = 0; i < v.cnt; ++i) // Fill the gap
arrPtr[i+pos] = v.arrPtr[i];
cnt = cnt + v.cnt;
}
Trang 2// To delete void FloatArr::remove(int pos) throw(BadIndex) {
if( pos >= 0 && pos < cnt) {
for( int i = pos; i < cnt-1; ++i) arrPtr[i] = arrPtr[i+1];
cnt;
} else throw BadIndex(pos);
} // -// arr_h.cpp
// Tests exception handling for float arrays
//
-#include <iostream>
#include <iomanip>
using namespace std;
#include "floatArr.h"
int main() {
const FloatArr v(10, 9.9f);
bool ok = false;
while( !ok) {
try { cout << "Here is the constant array v: \n";
cout << setw(8) << v <<endl;
int i;
cout << "Index? "; cin >> i;
cout << "\nThe value read: " << v[i] << endl;
ok = true;
} catch(BadIndex& err) {
cerr << "Error in reading.\n"
<< "\nInvalid index: "
<< err.getBadIndex() << endl;
} }
Trang 3FloatArr w(20); // Array w
try
{
w.insert(1.1F, 0); // To write
w.insert(2.2F, 1);
// w.insert(3.3F, 3); // Error!
// w[10] = 5.0; // Error!
// w.remove(7); // Error!
}
catch(BadIndex& err)
{
cerr << "\nError in writing! "
<< "\nInvalid index: "
<< err.getBadIndex() << endl;
}
cout << "\nHere is the array: \n";
cout << setw(5) << w << endl;
return 0;
}
Exercise 2
//
-// fraction.h
// A numeric class to represent fractions,
// exception handling is included
//
-#ifndef _FRACTION_
#define _FRACTION_
#include <iostream>
#include <cstdlib>
using namespace std;
class Fraction
{
private:
long numerator, denominator;
public:
class DivisionByZero
{
// No data members
};
Fraction(long z = 0, long n = 1) throw(DivisionByZero); Fraction operator-() const
{
return Fraction(-numerator, denominator);
}
Trang 4Fraction& operator+=(const Fraction& a) {
numerator = a.numerator * denominator
+ numerator * a.denominator;
denominator *= a.denominator;
return *this;
} Fraction& operator-=(const Fraction& a) {
*this += (-a);
return *this;
} Fraction& operator++() {
numerator += denominator;
return *this;
} Fraction& operator () {
numerator -= denominator;
return *this;
} friend Fraction operator+(const Fraction&,
const Fraction&);
friend Fraction operator-(const Fraction&,
const Fraction&);
friend Fraction operator*(const Fraction&,
const Fraction&);
friend Fraction operator/(const Fraction&,
const Fraction&) throw(Fraction::DivisionByZero); friend ostream& operator<<(ostream&, const Fraction&); friend istream& operator>>(istream& is, Fraction& a)
throw(Fraction::DivisionByZero); };
#endif
Trang 5// -// fraction.cpp
// Defines methods and friend functions
//
-#include <iostream>
#include <cstdlib>
using namespace std;
#include "fraction.h"
// Constructor:
Fraction::Fraction(long z, long n)
throw(Fraction::DivisionByZero) {
if(n == 0) throw DivisionByZero();
if( n < 0) z = -z, n = -n;
numerator = z; denominator = n;
}
Fraction operator+(const Fraction& a, const Fraction& b)
{
Fraction temp;
temp.denominator = a.denominator * b.denominator;
temp.numerator = a.numerator*b.denominator
+ b.numerator * a.denominator;
return temp;
}
Fraction operator-(const Fraction& a, const Fraction& b )
{
Fraction temp = a; temp += (-b);
return temp;
}
Fraction operator*(const Fraction& a, const Fraction& b )
{
Fraction temp;
temp.numerator = a.numerator * b.numerator;
temp.denominator = a.denominator * b.denominator;
return temp;
}
Fraction operator/(const Fraction& a, const Fraction& b )
throw(Fraction::DivisionByZero) {
if( b.numerator == 0) throw Fraction::DivisionByZero(); // Multiply a with the inverse of b:
Fraction temp;
temp.numerator = a.numerator * b.denominator;
temp.denominator = a.denominator * b.numerator;
if( temp.denominator < 0 )
temp.numerator = -temp.numerator,
temp.denominator = -temp.denominator;
return temp;
}
Trang 6ostream& operator<<(ostream& os, const Fraction& a) {
os << a.numerator << "/" << a.denominator;
return os;
} istream& operator>>(istream& is, Fraction& a)
throw(Fraction::DivisionByZero) {
cout << "Enter a fraction:\n"
" Numerator: "; is >> a.numerator;
cout << " Denominator != 0: "; is >> a.denominator; if( !is) return is;
if( a.denominator == 0) {
cout << "\nError: The denominator is 0\n"
<< "New Denominator != 0: "; is >> a.denominator; }
if( a.denominator == 0) throw Fraction::DivisionByZero();
if( a.denominator < 0 ) a.numerator = -a.numerator, a.denominator = -a.denominator;
return is;
}
// -// fract_t.cpp : Testing the class Fraction
// Modules: fract_t.cpp fraction.cpp //
-#include <iostream.h>
#include "fraction.h"
int main() {
try // Tests the exception of the constructor: {
Fraction c(5,0);
} catch(Fraction::DivisionByZero& ) {
cout << "\nError on initializing: "
<< "\nThe denominator is 0\n";
}
Trang 7Fraction a(1,3), b(3);
try
{
cout << "\nSome test output:\n\n";
cout << " a = " << a << endl;
cout << " b = " << b << endl;
cout << " a + b = " << (a + b) << endl;
cout << " a - b = " << (a - b) << endl;
cout << " a * b = " << (a * b) << endl;
b = 0;
cout << " a / b = " << (a / b) << endl; // Error!
}
catch(Fraction::DivisionByZero& )
{
cout << "\nError on dividing: "
<< "\nNo division by zero! 0\n";
}
cout << " a = " << a << endl;
cout << " ++a = " << ++a << endl;
a += Fraction(1,2);
cout << " a+= 1/2; a = " << a << endl;
a -= Fraction(1,2);
cout << " a-= 1/2; a = " << a << endl;
cout << "-b = " << -b << endl;
cout << "\nAnd now your input: \n";
try
{
cin >> a;
}
catch(Fraction::DivisionByZero&)
{
cerr << "\nError: The denominator is 0\n";
exit(1);
}
cout << "\nYour input: " << a << endl;
return 0;
}
Trang 96 3 7
More about Files
This chapter describes
■ random access to files based on file streams
■ options for querying file state
■ exception handling for files.
We will also illustrate how to make objects in polymorphic classes persistent, that is, how to save them in files.The applications introduced in this chapter include simple index files and hash tables.
Trang 10Open mode Effects Must the file
exist?
To open the file for input and output.
Opens the file for input and output If the file already exists,
it will be truncated.
Opens the file for input and output If the file does not exist,
it will be created.
Before each writing access, a seek to end is performed.
yes
no
no
ios::in
| ios::out ios::in
| ios::out
| ios::trunc ios::in
| ios::out
| ios::app
1 If the flag ios::binary is additionally set, the file will be opened in binary mode.
2 If the flag ios::ate (“at end”) is additionally set, the current seek position is set to end-of-file immediately after opening.
✓ NOTE
■ OPENING A FILE FOR RANDOM ACCESS
Combined open modes for read and write access