home *** CD-ROM | disk | FTP | other *** search
/ C Programming Starter Kit 2.0 / SamsPublishing-CProgrammingStarterKit-v2.0-Win31.iso / bc45 / labels.pak / LABELS.CPP next >
C/C++ Source or Header  |  1997-07-23  |  26KB  |  623 lines

  1. /*------------------------------------------------------------------------*/
  2. /*                                                                        */
  3. /*  LABELS.CPP                                                            */
  4. /*                                                                        */
  5. /*  Copyright (c) 1993 Borland International                              */
  6. /*  All Rights Reserved                                                   */
  7. /*                                                                        */
  8. /*  Classes Used: TISListImp, string, TDate, ipstream, opstream.          */
  9. /*                                                                        */
  10. /*  Description:                                                          */
  11. /*                                                                        */
  12. /*      Updates and displays the contents of a mailing list.              */
  13. /*                                                                        */
  14. /*  Usage:                                                                */
  15. /*                                                                        */
  16. /*      LABELS <master file> [<new subscription file?]                    */
  17. /*                                                                        */
  18. /*      Creates the master file if it does not exist. If new              */
  19. /*      subscription file is specified, reads the file and inserts        */
  20. /*      the new subscriptions into the master file. Prints the            */
  21. /*      contents of the master file to standard out in label format.      */
  22. /*                                                                        */
  23. /*  Subscription File Format:                                             */
  24. /*                                                                        */
  25. /*      The format of each new subscription record is as follows:         */
  26. /*                                                                        */
  27. /*          <name>;<street>;<city>;<state>;<zip>;<expiration date>        */
  28. /*                                                                        */
  29. /*------------------------------------------------------------------------*/
  30.  
  31. #include <classlib\listimp.h>
  32. #include <classlib\objstrm.h>
  33. #include <classlib\date.h>
  34. #include <cstring.h>
  35. #include <fstream.h>
  36.  
  37. /*------------------------------------------------------------------------*/
  38. /*                                                                        */
  39. /*  class TSubscriber                                                     */
  40. /*                                                                        */
  41. /*  TSubscriber holds the name and address of a subscriber.               */
  42. /*                                                                        */
  43. /*  TSubscriber Public Interface                                          */
  44. /*  ----------------------------                                          */
  45. /*                                                                        */
  46. /*      TSubscriber();          Default constructor.                      */
  47. /*                                                                        */
  48. /*      TSubscriber( string name,                                         */
  49. /*                   string address,                                      */
  50. /*                   string city,                                         */
  51. /*                   string state,                                        */
  52. /*                   string zip );                                        */
  53. /*                              Constructor.                              */
  54. /*                                                                        */
  55. /*      string GetName() const; Returns the name of the subscriber.       */
  56. /*                                                                        */
  57. /*      string GetAddress() const;                                        */
  58. /*                                                                        */
  59. /*                              Returns the street address of             */
  60. /*                              the subscriber.                           */
  61. /*                                                                        */
  62. /*      string GetCity() const; Returns the city where the                */
  63. /*                              subscriber lives.                         */
  64. /*                                                                        */
  65. /*      string GetState() const;                                          */
  66. /*                              Returns the state where the               */
  67. /*                              subscriber lives.                         */
  68. /*                                                                        */
  69. /*      string GetZip() const;  Returns the subscriber's zipcode.         */
  70. /*                                                                        */
  71. /*      ostream& operator << ( ostream&, const TSubscriber& );            */
  72. /*                              Writes the subscriber's name and address, */
  73. /*                              formatted as a mailing label, to the      */
  74. /*                              ostream.                                  */
  75. /*                                                                        */
  76. /*      opstream& operator << ( opstream&, const TSubscriber& );          */
  77. /*                              Writes the subscriber's name and address  */
  78. /*                              to an opstream.                           */
  79. /*                                                                        */
  80. /*      ipstream& operator >> ( ipstream&, TSubscriber& );                */
  81. /*                              Reads a subscriber's name and address,    */
  82. /*                              written with the opstream inserter, from  */
  83. /*                              an ipstream.                              */
  84. /*                                                                        */
  85. /*------------------------------------------------------------------------*/
  86.  
  87. class TSubscriber
  88. {
  89.  
  90. public:
  91.  
  92.     TSubscriber() {}
  93.     TSubscriber( string name, string address,
  94.                  string city, string state, string zip );
  95.  
  96.     friend ostream& operator << ( ostream&, const TSubscriber& );
  97.  
  98.     friend opstream& operator << ( opstream&, const TSubscriber& );
  99.     friend ipstream& operator >> ( ipstream&, TSubscriber& );
  100.  
  101.     string GetName() const;
  102.     string GetAddress() const;
  103.     string GetCity() const;
  104.     string GetState() const;
  105.     string GetZip() const;
  106.  
  107. private:
  108.  
  109.     string Name;
  110.     string Address;
  111.     string City;
  112.     string State;
  113.     string Zip;
  114.  
  115.     enum { Version = 1 };
  116.  
  117. };
  118.  
  119. //
  120. //  Construct a TSubscriber object from its component parts.
  121. //
  122.  
  123. TSubscriber::TSubscriber( string name, string address,
  124.                           string city, string state, string zip ) :
  125.     Name(name), Address(address),
  126.     City(city), State(state), Zip(zip)
  127. {
  128. }
  129.  
  130. //
  131. //  Write a TSubscriber object to a stream in a format suitable
  132. //  for a mailing label.
  133. //
  134.  
  135. ostream& operator << ( ostream& out, const TSubscriber& sub )
  136. {
  137.     out << sub.Name << '\n'
  138.         << sub.Address << '\n'
  139.         << sub.City << ", " << sub.State << " " << sub.Zip << '\n'
  140.         << endl;
  141.     return out;
  142. }
  143.  
  144. //
  145. //  Write a TSubscriber object to an opstream in a format suitable
  146. //  for reading with the extractor that follows.
  147. //
  148.  
  149. opstream& operator << ( opstream& out, const TSubscriber& sub )
  150. {
  151.     out << TSubscriber::Version;
  152.     out << sub.Name << sub.Address
  153.         << sub.City << sub.State << sub.Zip;
  154.     return out;
  155. }
  156.  
  157. //
  158. //  Read a subscriber's name and address from an ipstream created
  159. //  with the preceding inserter.
  160. //
  161.  
  162. ipstream& operator >> ( ipstream& in, TSubscriber& sub )
  163. {
  164.     int ver;
  165.     in >> ver;
  166.     if( ver > TSubscriber::Version )
  167.         in.clear( ios::failbit );   // bad object version
  168.  
  169.     in >> sub.Name >> sub.Address
  170.        >> sub.City >> sub.State >> sub.Zip;
  171.     return in;
  172. }
  173.  
  174. inline string TSubscriber::GetName() const
  175. {
  176.     return Name;
  177. }
  178.  
  179. inline string TSubscriber::GetAddress() const
  180. {
  181.     return Address;
  182. }
  183.  
  184. inline string TSubscriber::GetCity() const
  185. {
  186.     return City;
  187. }
  188.  
  189. inline string TSubscriber::GetState() const
  190. {
  191.     return State;
  192. }
  193.  
  194. inline string TSubscriber::GetZip() const
  195. {
  196.     return Zip;
  197. }
  198.  
  199. /*------------------------------------------------------------------------*/
  200. /*                                                                        */
  201. /*  class TSubscriptionInfo                                               */
  202. /*                                                                        */
  203. /*  TSubscriptionInfo holds subscriber information and the expiration     */
  204. /*  date for a subscription.                                              */
  205. /*                                                                        */
  206. /*  TSubscriptionInfo Public Interface                                    */
  207. /*  ----------------------------------                                    */
  208. /*                                                                        */
  209. /*      TSubscriptionInfo();    Default constructor.                      */
  210. /*                                                                        */
  211. /*      TSubscriptionInfo( string name,                                   */
  212. /*                         string address,                                */
  213. /*                         string city,                                   */
  214. /*                         string state,                                  */
  215. /*                         string zip,                                    */
  216. /*                         TDate expirationDate );                        */
  217. /*                              Constructor.                              */
  218. /*                                                                        */
  219. /*      int operator == ( const TSubscriptionInfo& );                     */
  220. /*                              Compares zip codes to determine           */
  221. /*                              equality.                                 */
  222. /*                                                                        */
  223. /*      int operator <  ( const TSubscriptionInfo& );                     */
  224. /*                              Compares zip codes to determine           */
  225. /*                              relative order in mailing list.           */
  226. /*                                                                        */
  227. /*      int HasExpired()        Returns 1 to indicate that the            */
  228. /*                              subscription has expired, 0 otherwise.    */
  229. /*                                                                        */
  230. /*      ostream& operator << ( ostream&, const TSubscriptionInfo& );      */
  231. /*                              Writes the subscriber's name and address, */
  232. /*                              formatted as a mailing label, to the      */
  233. /*                              ostream.                                  */
  234. /*                                                                        */
  235. /*      opstream& operator << ( opstream&, const TSubscriber& );          */
  236. /*                              Writes the subscription information       */
  237. /*                              to an opstream.                           */
  238. /*                                                                        */
  239. /*      ipstream& operator >> ( ipstream&, TSubscriber& );                */
  240. /*                              Reads subscription information, written   */
  241. /*                              with the opstream inserter, from an       */
  242. /*                              ipstream.                                 */
  243. /*                                                                        */
  244. /*------------------------------------------------------------------------*/
  245.  
  246. class TSubscriptionInfo
  247. {
  248. public:
  249.  
  250.     TSubscriptionInfo() {}
  251.     TSubscriptionInfo( string name, string address,
  252.                        string city, string state, string zip,
  253.                        TDate expirationDate);
  254.  
  255.     int operator == ( const TSubscriptionInfo& o );
  256.     int operator <  ( const TSubscriptionInfo& o );
  257.  
  258.     int HasExpired();
  259.  
  260.     friend ostream& operator << ( ostream&, const TSubscriptionInfo& );
  261.  
  262.     friend opstream& operator << ( opstream&, const TSubscriptionInfo& );
  263.     friend ipstream& operator >> ( ipstream&, TSubscriptionInfo& );
  264.  
  265. private:
  266.  
  267.     TSubscriber Subscriber;
  268.     TDate ExpirationDate;
  269.  
  270.     enum { Version = 1 };
  271.  
  272. };
  273.  
  274. TSubscriptionInfo::TSubscriptionInfo( string name, string address,
  275.                                       string city, string state, string zip,
  276.                                       TDate expirationDate) :
  277.     Subscriber( name, address, city, state, zip ),
  278.     ExpirationDate( expirationDate )
  279. {
  280. }
  281.  
  282. int TSubscriptionInfo::operator == ( const TSubscriptionInfo& o )
  283. {
  284.     return Subscriber.GetZip() == o.Subscriber.GetZip();
  285. }
  286.  
  287. int TSubscriptionInfo::operator < ( const TSubscriptionInfo& o )
  288. {
  289.     return Subscriber.GetZip() < o.Subscriber.GetZip();
  290. }
  291.  
  292. int TSubscriptionInfo::HasExpired()
  293. {
  294.     return ExpirationDate < TDate();
  295. }
  296.  
  297. ostream& operator << ( ostream& out, const TSubscriptionInfo& sub )
  298. {
  299.     out << sub.Subscriber << endl;
  300.     return out;
  301. }
  302.  
  303. opstream& operator << ( opstream& out, const TSubscriptionInfo& sub )
  304. {
  305.     out << TSubscriptionInfo::Version;
  306.     out << sub.Subscriber << sub.ExpirationDate;
  307.     return out;
  308. }
  309.  
  310. ipstream& operator >> ( ipstream& in, TSubscriptionInfo& sub )
  311. {
  312.     int ver;
  313.     in >> ver;
  314.     if( ver > TSubscriptionInfo::Version )
  315.         in.clear( ios::failbit );   // bad object version
  316.  
  317.     in >> sub.Subscriber >> sub.ExpirationDate;
  318.     return in;
  319. }
  320.  
  321. /*------------------------------------------------------------------------*/
  322. /*                                                                        */
  323. /*  class TSubscriptionList                                               */
  324. /*                                                                        */
  325. /*  TSubscriptionList maintains a list of subscribers sorted by zip code. */
  326. /*                                                                        */
  327. /*  TSubscriptionList Public Interface                                    */
  328. /*  ----------------------------------                                    */
  329. /*                                                                        */
  330. /*  TSubscriptionList( string fileName );                                 */
  331. /*                              Constructor. Initializes the subscription */
  332. /*                              list from the specified file if it        */
  333. /*                              exists. This should be a file created by  */
  334. /*                              a TSubscriptionList object.               */
  335. /*                                                                        */
  336. /*  ~TSubscriptionList();       Destructor. Writes the subscription list  */
  337. /*                              out to the file specified in the          */
  338. /*                              constructor. Overwrites the old data if   */
  339. /*                              the file already exists, otherwise        */
  340. /*                              creates a new file.                       */
  341. /*                                                                        */
  342. /*  int AddSubscription( const TSubscriptionInfo& );                      */
  343. /*                              Adds a new subscription to the list.      */
  344. /*                                                                        */
  345. /*  void PrintLabels( ostream& );                                         */
  346. /*                              Prints the subscription list as a series  */
  347. /*                              of address labels to the specified        */
  348. /*                              output stream.                            */
  349. /*                                                                        */
  350. /*------------------------------------------------------------------------*/
  351.  
  352. class TSubscriptionList
  353. {
  354.  
  355. public:
  356.  
  357.     TSubscriptionList( string fileName );
  358.     ~TSubscriptionList();
  359.  
  360.     int AddSubscription( const TSubscriptionInfo& );
  361.     void PrintLabels( ostream& );
  362.  
  363. private:
  364.  
  365.     void ReadStream( ipstream& );
  366.     void WriteStream( opstream& );
  367.  
  368.     string FileName;
  369.     TISListImp<TSubscriptionInfo> Subscriptions;
  370.     static void PrintLabel( TSubscriptionInfo &i, void *arg );
  371.  
  372.     enum { Version = 1 };
  373.  
  374. };
  375.  
  376. TSubscriptionList::TSubscriptionList( string fileName ) :
  377.     FileName(fileName)
  378. {
  379.     ifpstream in( FileName.c_str() );
  380.     if( in )
  381.         ReadStream( in );
  382. }
  383.  
  384. TSubscriptionList::~TSubscriptionList()
  385. {
  386.     ofpstream out( FileName.c_str() );
  387.     WriteStream( out );
  388. }
  389.  
  390. int TSubscriptionList::AddSubscription( const TSubscriptionInfo& sub )
  391. {
  392.     return Subscriptions.Add( new TSubscriptionInfo(sub) );
  393. }
  394.  
  395. void TSubscriptionList::PrintLabels( ostream& out )
  396. {
  397.     cerr << "Printing labels...\n";
  398.     Subscriptions.ForEach( PrintLabel, &(ostream&)out );
  399.     cerr << "Finished printing labels.\n";
  400. }
  401.  
  402.  
  403. void TSubscriptionList::PrintLabel( TSubscriptionInfo &i, void *strm )
  404. {
  405.     *(ostream *)strm << i;
  406. }
  407.  
  408. void TSubscriptionList::WriteStream( opstream& out )
  409. {
  410.     out << Version;
  411.     out << Subscriptions.GetItemsInContainer();
  412.     TISListIteratorImp<TSubscriptionInfo> iter( Subscriptions );
  413.  
  414.     while( iter != 0 )
  415.         out << *(iter++);
  416. }
  417.  
  418. void TSubscriptionList::ReadStream( ipstream& in )
  419. {
  420.     int ver;
  421.     in >> ver;
  422.     if( ver > Version )
  423.         in.clear( ios::failbit );   // bad object version
  424.     else
  425.         {
  426.         unsigned count;
  427.  
  428.         in >> count;
  429.         for( unsigned i = 0; i < count; i++ )
  430.             {
  431.             TSubscriptionInfo si;
  432.             in >> si;
  433.             if( si.HasExpired() )
  434.                 {
  435.                 cerr << "Subscription has expired:\n";
  436.                 cerr << si << endl;
  437.                 }
  438.             else
  439.                 AddSubscription( si );
  440.             }
  441.         }
  442. }
  443.  
  444. /*------------------------------------------------------------------------*/
  445. /*                                                                        */
  446. /*  class TNewSubscribers                                                 */
  447. /*                                                                        */
  448. /*  TNewSubscribers parses a subscriber list from a text file and inserts */
  449. /*  the subscriptions into a TSubscriptionList object.                    */
  450. /*                                                                        */
  451. /*  TNewSubscribers Public Interface                                      */
  452. /*  --------------------------------                                      */
  453. /*                                                                        */
  454. /*  TNewSubscribers( string fileName, TSubscriptionList& list );          */
  455. /*                              Constructor. Parameters are the name of   */
  456. /*                              the text file to read from and a          */
  457. /*                              reference to the subscriber list to add   */
  458. /*                              subscribers to.                           */
  459. /*                                                                        */
  460. /*  void Update();              Add the subscribers to the subscriber     */
  461. /*                              list.                                     */
  462. /*                                                                        */
  463. /*------------------------------------------------------------------------*/
  464.  
  465. class TNewSubscribers
  466. {
  467.  
  468. public:
  469.  
  470.     TNewSubscribers( string fileName, TSubscriptionList& list );
  471.  
  472.     void Update();
  473.  
  474. private:
  475.  
  476.     string FileName;
  477.     TSubscriptionList& List;
  478.  
  479. };
  480.  
  481. TNewSubscribers::TNewSubscribers( string fileName, TSubscriptionList& list ) :
  482.     FileName(fileName),
  483.     List(list)
  484. {
  485. }
  486.  
  487. void TNewSubscribers::Update()
  488. {
  489.     ifstream newSubscriptions( FileName.c_str() );
  490.  
  491.     cerr << "\nProcessing subscriptions...\n";
  492.     while( newSubscriptions )
  493.         {
  494.         string name;
  495.         string address;
  496.         string city;
  497.         string state;
  498.         string zip;
  499.         TDate expirationDate;
  500.  
  501.         char buf[256];
  502.  
  503.         newSubscriptions.getline( buf, sizeof(buf), ';' );
  504.         name = buf;
  505.  
  506.         newSubscriptions.getline( buf, sizeof(buf), ';' );
  507.         address = buf;
  508.  
  509.         newSubscriptions.getline( buf, sizeof(buf), ';' );
  510.         city = buf;
  511.  
  512.         newSubscriptions.getline( buf, sizeof(buf), ';' );
  513.         state = buf;
  514.  
  515.         newSubscriptions.getline( buf, sizeof(buf), ';' );
  516.         zip = buf;
  517.  
  518.         newSubscriptions >> expirationDate;
  519.  
  520.         if( !newSubscriptions )
  521.             cerr << "Invalid new subscription record." << endl;
  522.         else
  523.             {
  524.             TSubscriptionInfo newSubscription( name,
  525.                                                address,
  526.                                                city,
  527.                                                state,
  528.                                                zip,
  529.                                                expirationDate );
  530.  
  531.             if( newSubscription.HasExpired() )
  532.                 {
  533.                 cerr << "New subscription has expired:\n";
  534.                 cerr << newSubscription;
  535.                 }
  536.             else
  537.                 List.AddSubscription( newSubscription );
  538.             }
  539.         newSubscriptions >> ws;
  540.         }
  541. }
  542.  
  543. /*------------------------------------------------------------------------*/
  544. /*                                                                        */
  545. /*  Support functions and main()                                          */
  546. /*                                                                        */
  547. /*  voidSignOn();               Displays the program's banner.            */
  548. /*                                                                        */
  549. /*  void Usage();               Displays usage instructions.              */
  550. /*                                                                        */
  551. /*  void ShowList( string masterFileName );                               */
  552. /*                              Writes mailing labels from the file       */
  553. /*                              named by masterFileName to standard out.  */
  554. /*                                                                        */
  555. /*  void UpdateList( string masterFileName, string newSubFileName );      */
  556. /*                              Adds the subscriptions from               */
  557. /*                              to the mailing list in masterFileName,    */
  558. /*                              then writes mailing labels from           */
  559. /*                              masterFileName to standard out.           */
  560. /*                                                                        */
  561. /*  int main( int argc, char *argv[] );                                   */
  562. /*                              Parses the command line. If only one      */
  563. /*                              parameter is given, assumes that it is    */
  564. /*                              the name of a master file and prints      */
  565. /*                              mailing labels from that file. If two     */
  566. /*                              parameters are given, assumes that the    */
  567. /*                              first is the name of a master file and    */
  568. /*                              the second is the name of a new           */
  569. /*                              subscription file. Updates the master     */
  570. /*                              file from the new subscription file then  */
  571. /*                              prints mailing labels from the master     */
  572. /*                              file. If no parameters are given, or more */
  573. /*                              than two are given, displays usage        */
  574. /*                              instructions and exits.                   */
  575. /*                                                                        */
  576. /*------------------------------------------------------------------------*/
  577.  
  578. void SignOn()
  579. {
  580.     cerr << "Mailing Labels, version 1.00\n";
  581. }
  582.  
  583. void Usage()
  584. {
  585.     cerr << "\nSyntax: LABELS <master file> [<new subscription file>]\n"
  586.          << "\tIf both files names are present, updates master file\n"
  587.          << "\tfrom new subscription file then writes mailing labels to\n"
  588.          << "\tstandard out. Otherwise writes mailing labels to standard out.\n";
  589. }
  590.  
  591. void ShowList( string masterFileName )
  592. {
  593.     TSubscriptionList SubList( masterFileName );
  594.     SubList.PrintLabels(cout);
  595. }
  596.  
  597. void UpdateList( string masterFileName, string newSubFileName )
  598. {
  599.     TSubscriptionList SubList( masterFileName );
  600.     TNewSubscribers NewSubs( newSubFileName, SubList );
  601.     NewSubs.Update();
  602.     SubList.PrintLabels(cout);
  603. }
  604.  
  605. int main (int argc, char *argv[])
  606. {
  607.     SignOn();
  608.     switch( argc )
  609.         {
  610.         case 2:
  611.             ShowList( argv[1] );
  612.             break;
  613.         case 3:
  614.             UpdateList( argv[1], argv[2] );
  615.             break;
  616.         default:
  617.             Usage();
  618.             break;
  619.         }
  620.     return 0;
  621. }
  622.  
  623.