The Mailing Lis t Application
This appendix shows a complete program that contains most the commands and functions you learned in this book. This program manages a mailing list for your personal or business needs.
When you run the program, you are presented with a menu of choices that guides you through the program’s operation. Comments throughout the program offer improvements you might want to make. As your knowledge and practice of C++ improve, you might want to expand this mailing list application into a complete database of contacts and relatives.
Here is the listing of the complete program:
/ / Fil ename: MAI LI NG. CPP
/ / * Maili ng Li st Appli cat i on *
/ / ------------------------
/ /
/ / Thi s pr ogr am enabl es t he user t o ent er , edi t , mai nt ai n, and
/ / pr i nt a maili ng li st of names and addr esses.
/ /
/ / All commands and concept s i ncl uded i n t hi s pr ogr am ar e
/ / expl ai ned t hr oughout t he t ext of C++ By Exampl e.
/ /
/ /
/ /
/ / These ar e i t ems you mi ght want t o add or change:
/ / 1. Fi nd your compil er ’ s cl ear scr een f unct i on t o
/ / i mpr ove upon t he scr een- cl ear i ng f unct i on.
/ / 2. Add an ent r y f or t he ‘ code’ member t o t r ack di ff er ent
/ / t ypes of names and addr esses ( i . e. , busi ness codes,
/ / per sonal codes, et c. )
/ / 3. Sear ch f or a par t i al name ( i . e. , t ypi ng “ Sm” f i nds
/ / “ Smi t h” and “ Smi tt y” and “ Smyt he” i n t he f il e) .
/ / 4. When sear chi ng f or name mat ches, i gnor e case ( i . e.,
/ / t ypi ng “ smi t h” f i nds “ Smi t h” i n t he f il e) .
/ / 5. Pr i nt maili ng l abel s on your pr i nt er .
/ / 6. All ow f or sor t i ng a li st i ng of names and addr ess by name
/ / or ZI P code.
/ / Header f il es used by t he pr ogr am: #i ncl ude <coni o. h>
#i ncl ude <ct ype. h> #i ncl ude <f st r eam. h>
#i ncl ude <i ost r eam. h> #i ncl ude <st r i ng. h>
const char FI LENAME[ ] = “ ADDRESS. DAT” ;
/ / Pr ot ot ype all of t hi s pr ogr am’ s f unct i ons. char get _answer( voi d) ;
voi d di sp_menu ( voi d) ; voi d cl ear _sc ( voi d) ; voi d change_na ( voi d) ; voi d pr i nt _na ( voi d) ;
voi d err _msg ( char err _msg[ ] ) ; voi d pause_sc ( voi d) ;
const i nt NAME_SI ZE = 25; const i nt ADDRESS_SI ZE = 25; const i nt CI TY_SI ZE = 12;
const i nt STATE_SI ZE = 3; const i nt ZI PCODE_SI ZE = 6; const i nt CODE_SI ZE = 7;
/ / Cl ass of a name and addr ess cl ass Mail
{
pr i vat e:
char name[ NAME_SI ZE] ; / / Name st or ed her e, shoul d
/ / be Last , Fi r st or der char addr ess[ ADDRESS_SI ZE];
char ci t y[ CI TY_SI ZE];
char st at e[ STATE_SI ZE] ; / / Save r oom f or null zer o. char zi pcode[ ZI PCODE_SI ZE];
char code[ CODE_SI ZE] ; / / For addi t i onal expansi on. You
/ / mi ght want t o use t hi s member
/ / f or cust omer codes, vendor codes,
/ / or holi day car d codes.
publ i c:
voi d pr _dat a( Mail * i t em)
{
/ / Pr i nt s t he name and addr ess sent t o i t.
cout << “ \ nName : “ << ( * i t em) . name << “ \ n” ; cout << “ Addr ess: “ << ( * i t em) . addr ess << “ \ n” ; cout << “ Ci t y : “ << ( * i t em) . ci t y << “ \t St at e: “
<< ( * i t em) . st at e << “ Zi pcode: “ << ( * i t em) . zi pcode
<< “ \ n” ;
}
voi d get _new_i t em( Mail * i t em)
{
Mail t emp_i t em; / / Hol ds t empor ar y changed i nput.
cout << “ \ nEnt er new name and addr ess i nf ormat i on bel ow\ n( Pr ess t he “ ; cout << “ Ent er key wi t hout t ypi ng dat a t o r et ai n ol d "
“ i nf ormat i on) \ n\ n” ;
cout << “ What i s t he new name? “ ;
ci n. get li ne( t emp_i t em. name, NAME_SI ZE) ;
i f ( st r l en( t emp_i t em. name)) / / Onl y save new dat a i f user
{ st r cpy(( * i t em) . name, t emp_i t em. name) ; } / / t ypes somet hi ng. cout << “ What i s t he addr ess? “ ;
ci n. get li ne( t emp_i t em. addr ess, ADDRESS_SI ZE) ;
i f ( st r l en( t emp_i t em. addr ess))
{ st r cpy(( * i t em) . addr ess, t emp_i t em. addr ess) ; } cout << “ What i s t he ci t y? “ ;
ci n. get li ne( t emp_i t em. ci t y, CI TY_SI ZE) ; i f ( st r l en( t emp_i t em. ci t y))
{ st r cpy(( * i t em) . ci t y, t emp_i t em. ci t y) ; }
cout << “ What i s t he st at e? ( 2 l ett er abbr evi at i on onl y) “ ; ci n. get li ne( t emp_i t em. st at e, STATE_SI ZE) ;
i f ( st r l en( t emp_i t em. st at e))
{ st r cpy(( * i t em) . st at e, t emp_i t em. st at e) ; } cout << “ What i s t he ZI P code? “ ;
ci n. get li ne( t emp_i t em. zi pcode, ZI PCODE_SI ZE) ; i f ( st r l en( t emp_i t em. zi pcode))
{ st r cpy(( * i t em) . zi pcode, t emp_i t em. zi pcode) ; }
( * i t em) . code[ 0] = 0; / / Null out t he code member
/ / ( unused her e) .
}
voi d add_t o_f il e( Mail * i t em) ; voi d change_na( voi d) ;
voi d ent er _na( Mail * i t em) ; voi d get zi p( Mail * i t em) ;
} ;
voi d Mail :: change_na( voi d)
{
/ / Thi s sear ch f unct i on can be i mpr oved by usi ng t he
/ / code member t o assi gn a uni que code t o each per son on t he
/ / li st . Names ar e di ff i cul t t o sear ch f or si nce t her e ar e
/ / so many var i at i ons ( such as Mc and Mac and St . and Sai nt ) .
Mail i t em;
f st r eam f il e; i nt ans;
i nt s; / / Hol ds si ze of st r uct ur e.
i nt change_yes = 0; / / Will become TRUE i f user f i nds char t est _name[ 25] ; / / a name t o change.
cout << “ \ nWhat i s t he name of t he per son you want t o change? “ ; ci n. get li ne( t est _name, NAME_SI ZE) ;
s = si zeof ( Mail ) ; / / To ensur e f r ead() r eads pr oper l y.
f il e. open( FI LENAME, i os:: i n | i os:: out ) ; i f ( !f il e)
{
err _msg(“ *** Read err or - Ensur e f il e exi st s bef or e " " r eadi ng i t ***”) ;
r et ur n;
}
do
{
f il e. r ead(( unsi gned char * ) &i t em, si zeof ( Mail )) ; i f ( f il e. gcount () ! = s)
{
i f ( f il e. eof ())
{ br eak; }
}
i f ( st r cmp( i t em. name, t est _name) == 0)
{
i t em. pr _dat a( &i t em) ; / / Pr i nt name and addr ess. cout << “ \ nI s t hi s t he name and addr ess t o “ <<
“ change? ( Y/ N) “ ; ans = get _answer() ;
i f ( t oupper( ans) == ‘ N’ )
{ br eak; } / / Get anot her name.
get _new_i t em( &i t em) ; / / Enabl e user t o t ype new
/ / i nf ormat i on.
f il e. seekg(( l ong)- s, i os:: cur) ; / / Back up a st r uct ur e. f il e. wr i t e(( const unsi gned char *)( &i t em) ,
si zeof ( Mail )) ; / / Rewr i t e i nf ormat i on. change_yes = 1; / / Changed f l ag.
br eak; / / Fi ni shed
}
}
whil e ( !f il e. eof ()) ; i f ( ! change_yes)
{ err _msg(“ *** End of f il e encount er ed bef or e f i ndi ng t he name ***”) ; }
}
voi d Mail :: get zi p( Mail * i t em) / / Ensur e t hat ZI P code
/ / i s all di gi t s.
{
i nt ct r ;
i nt bad_zi p;
do
{
bad_zi p = 0;
cout << “ What i s t he ZI P code? “ ;
ci n. get li ne(( * i t em) . zi pcode, ZI PCODE_SI ZE) ; f or ( ct r = 0; ct r < 5; ct r ++)
{
i f ( i sdi gi t (( * i t em) . zi pcode[ ct r ] ))
{ cont i nue; } el se
{
err _msg(“ *** The ZI P code must consi st of di gi t s onl y ***”) ; bad_zi p = 1;
br eak;
}
}
}
whil e ( bad_zi p) ;
}
voi d Mail :: add_t o_f il e( Mail * i t em)
{
of st r eam f il e;
f il e. open( FI LENAME, i os:: app) ; / / Open f il e i n append mode. i f ( !f il e)
{
err _msg(“ *** Di sk err or - pl ease check di sk dr i ve ***”) ; r et ur n;
}
f il e. wr i t e(( const unsi gned char *)( i t em) , si zeof ( Mail )) ;
/ / Add st r uct ur e t o f il e.
}
voi d Mail :: ent er _na( Mail * i t em)
{
char ans;
do
{
cout << “ \ n\ n\ n\ n\ nWhat i s t he name? “ ; ci n. get li ne(( * i t em) . name, NAME_SI ZE) ; cout << “ What i s t he addr ess? “ ;
ci n. get li ne(( * i t em) . addr ess, ADDRESS_SI ZE) ; cout << “ What i s t he ci t y? “ ;
ci n. get li ne(( * i t em) . ci t y, CI TY_SI ZE) ;
cout << “ What i s t he st at e? ( 2 l ett er abbr evi at i on onl y)” ; ci n. get li ne(( * i t em) . st at e, STATE_SI ZE) ;
get zi p( i t em) ; / / Ensur e t hat ZI P code i s all di gi t s.
st r cpy(( * i t em) . code, “ “) ; / / Null out t he code member . add_t o_f il e( i t em) ; / / Wr i t e new i nf ormat i on t o di sk f il e. cout << “ \ n\ nDo you want t o ent er anot her name “ <<
“ and addr ess? ( Y/ N) “ ; ans = get _answer() ;
}
whil e ( t oupper( ans) == ‘ Y’ ) ;
}
/ / **** **** **** **** **** **** **** *** **** **** **** **** **** **** **** *
/ / Def i ned const ant s
/ / MAX i s t ot al number of names all owed i n memor y f or
/ / r eadi ng maili ng li st.
const i nt MAX = 250; const char BELL = ‘ \ x07’ ;
/ / **** **** **** **** **** **** **** *** **** **** **** **** **** **** **** * i nt mai n( voi d)
{
char ans; Mail i t em;
do
{
di sp_menu() ; / / Di spl ay t he menu f or t he user . ans = get _answer() ;
swi t ch ( ans)
{
case ‘ 1’ :
i t em. ent er _na( &i t em) ; br eak;
case ‘ 2’ :
i t em. change_na() ; br eak;
case ‘ 3’ :
pr i nt _na() ; br eak;
case ‘ 4’ :
br eak; def aul t:
err _msg(“ *** You have t o ent er 1 t hr ough 4 ***”) ; br eak;
}
}
whil e ( ans ! = ‘ 4’ ) ; r et ur n 0;
}
/ / **** **** **** **** **** **** **** *** **** **** **** **** **** **** **** *
voi d di sp_menu( voi d) / / Di spl ay t he mai n menu of pr ogr am.
{
cl ear _sc() ; / / Cl ear t he scr een.
cout << “ \t\t *** Maili ng Li st Manager *** \ n” ; cout << “ \ t \ t \ n\ n\ n\ n” ;
cout << “ Do you want t o:\ n\ n\ n” ;
cout << “ \t 1. Add names and addr esses t o t he li st\ n\
n\ n” ; cout << “ \t 2. Change names and addr esses i n t he
li st\ n\ n\ n” ; cout << “ \t 3. Pr i nt names and addr
esses i n t he li st\ n\ n\ n” ; cout << “ \t 4. Exi t t hi
s pr ogr am\ n\ n\ n” ;
cout << “ What i s your choi ce? “ ;
}
/ / **** **** **** **** **** **** **** *** **** **** **** **** **** **** **** *
voi d cl ear _sc() / / Cl ear t he scr een by sendi ng 25 bl ank
/ / li nes t o i t.
{
i nt ct r ; / / Count er f or t he 25 bl ank li nes. f or ( ct r = 0; ct r < 25; ct r ++)
{ cout << “ \ n” ; }
}
/ / **** **** **** **** **** **** **** *** **** **** **** **** **** **** **** *
voi d pr i nt _na( voi d)
{
Mail i t em;
i f st r eam f il e; i nt s;
i nt li nect r = 0;
s = si zeof ( Mail ) ; / / To ensur e f r ead() r eads pr oper l y. f il e. open( FI LENAME) ;
i f ( !f il e)
{
err _msg(“ *** Err or - Ensur e f il e exi st s bef or e" " r eadi ng i t ***”) ;
r et ur n;
}
do
{
f il e. r ead(( si gned char * ) &i t em, s) ; i f ( f il e. gcount () ! = s)
{
i f ( f il e. eof ()) / / I f EOF, qui t r eadi ng.
{ br eak; }
}
i f ( li nect r > 20) / / Scr een i s f ull .
{
pause_sc() ; li nect r = 0;
}
i t em. pr _dat a( &i t em) ; / / Pr i nt t he name and addr ess. li nect r += 4;
}
whil e ( !f il e. eof ()) ;
cout << “ \ n- End of li st -” ;
pause_sc() ; / / Gi ve user a chance t o see names
/ / r emai ni ng on- scr een.
}
/ / **** **** **** **** **** **** **** *** **** **** **** **** **** **** **** *
voi d err _msg( char err _msg[ ] )
{
cout << “ \ n\ n” << err _msg << BELL << “ \ n” ;
}
/ / **** **** **** **** **** **** **** *** **** **** **** **** **** **** **** *
voi d pause_sc()
{
cout << “ \ nPr ess t he Ent er key t o cont i nue... ” ; whil e ( get ch() ! = ‘ \ r ’ )
{ ; } / / Wai t f or Ent er key.
}
/ / **** **** **** **** **** **** **** *** **** **** **** **** **** **** **** *
char get _answer( voi d)
{
char ans;
ans = get ch() ; whil e ( kbhi t ())
{ get ch() ; } put ch( ans) ;
r et ur n ans;
}