Assignment 2
Version 1.0


EAN Processor - Object Version



In your second assignment you convert the global functions that you developed for assignment 1 into member functions. 


Learning Outcomes

Upon successful completion of this assignment, you will have demonstrated the abilities to

  1. convert a global function into a member function
  2. encapsulate data and logic within a class
  3. code a safe empty state
  4. pass a reference to an object

Styles

The three popular styles for printing registered EANs are:

  • blank style
  • dash style
  • concatenated style

In blank style, a single blank space separates the prefix, area, publisher and title elements

 978 0 00 319487 6

In dash style, a single dash character separates the four elements

 978-0-00-319487-6

Concatenated style has no separator

 9780003194876

We use concatenated style for input and unregistered EANs.  We use dash style as the default for registered EANs.


Specifications

The two classes developed in this assignment are named

  • Prefix
  • EAN

The global functions that you coded for assignment 1 contain the logic that you need for defining member functions of these two classes.  In converting the global functions into member functions, you will reduce the parameter lists and changing some identifiers, but should not need to change the algorithms themselves. 

Prefix Class

Class Definition

Your Prefix class manages access to the GS1 prefix table.  The data members remain unchanged.  Convert the struct definition to a class definition that includes the prototypes for your member functions. 

Member Functions

Your Prefix class includes the following member functions:

  • A one-argument constructor that receives the address of a C-style, null-terminated string containing the name of the file that holds the prefix table
     Prefix(const char* filename);
    

    This constructor loads the file data into the data members.  You may use the code from the load() function for this constructor. 

  • A query that receives an area identifier and determines if the area is listed in the prefix table
     bool isRegistered(int area) const;
    

    This function returns true if the area is an area element listed in the prefix table; false otherwise. 

  • A query that receives an area element and determines the minimum number of digits in any publisher identifier registered under that area in the prefix table
     int minNoDigits(int area) const;
    

    This function returns the minimum number of digits if the area element is in the prefix table; zero (0) otherwise. 

  • A query that receives an area element and a publisher element and determines if the publisher element is within one of the publisher ranges listed under that area element in the prefix table
     bool isRegistered(int area, const char* publisher) const;
    

    This function returns true if the publisher identifier is within a range listed under the area; false otherwise.  Note that the area parameter is of int data type and the publisher parameter receives the address of a C-style string.

Design each member function to yield a reasonable result even if it receives invalid values for any of its parameters. 

Replace the prototypes for your global functions in your GS1Prefix.h header file with your class definition.  Replace the global function definitions in your GS1Prefix.cpp implementation file with your member function definitions.

EAN Class

Your EAN class manages a single EAN.

Class Definition

Your EAN class holds the information in its data members that is common to the member functions.  Survey the member function specifications and identify these common data members.  They include the parameters that were in the first assignment but have been removed in this second assignment.

Member Functions

Your EAN class includes the following member functions:

  • A no-argument constructor that creates an EAN object in a safe empty state
     EAN();
    
  • A two-argument constructor that receives the address of a C-style null-terminated string and a reference to a Prefix object.  This constructor creates an EAN object from the string and checks for registration using the Prefix object
     EAN(const char* str, const Prefix& list);
    

    If the string is a valid EAN, this member function accepts the string and checks if the EAN is registered.  If registered, this member function also stores its area, publisher and title elements and initializes the style to the dash style.  If the string is not a valid EAN string, this constructor leaves the object in a safe empty state. 

  • A private modifier that receives a reference to an Prefix object and decomposes an EAN into its area, publisher and title elements
     bool isRegistered(const Prefix& list);
    

    If the EAN is registered, this function extracts the area, publisher, and title components and returns true.  If the EAN is not registered, this function returns false

  • A query that returns true if the object is in a safe empty state, false otherwise
     bool empty() const;
    
  • A query that returns true if the object is registered, false otherwise
     bool isRegistered() const;
    
  • A modifier that receives a char and sets the style to the character received if its value is one of the three legitimate values listed above
     void style(char);
    

    This function does nothing if the style character received is not legitimate.

  • A query that receives the address of a C-style, null-terminated string and fills that address with the object's EAN
     void toStr(char* str) const;
    

    This function assumes that the caller has allocated enough space to hold a thirteen (13) character string. 

  • A query that receives the address of a C-style, null-terminated string and fills that address with a formatted version of the object's EAN applying the current style
     void toStrWithStyle(char* str) const;
    

    The formatted string consists of the prefix, area, publisher and title elements separated by the style delimiter for a registered object (as shown above).  The string is in the concatenated style if the object is unregistered. 

    This function assumes that the caller has allocated enough space to hold up to a seventeen (17) character string.

  • A query that receives a reference to an ostream object and inserts the EAN string in the current style into output stream os 
     void display(std::ostream& os) const;
    

    If the EAN is not registered, this function displays it in concatenated style.  In either case, your function displays the EAN right-justified in a field of seventeen (17) characters.

    For example,

     978-0-00-319487-6
         9789995500009
    
  • A modifier that receives a reference to an istream object and a reference to a Prefix object.  This function reads a thirteen character string from the input stream and, if a valid EAN, accepts the string
     bool read(std::istream& is, const Prefix& list);
    

    This function prompts for and accepts a string of up to thirteen characters.  If the string contains exactly thirteen characters and those characters form a valid EAN, this function accepts the EAN and stores it in the current object.  If the input is unacceptable for any reason, this function requests another string or "0" to quit.  If the user enters "0", this function does not change the current object and returns false; true otherwise. 

Design each member function so that it yields a reasonable result even if the function receives invalid values in any of its parameters. 

Insert your class definition into your EAN.h header file before the prototype for your global isValid() function.  Replace the prototype for your global isRegistered() function with a member function prototype inside the class definition.  Preface your class definition with the following forward declaration

 class Prefix;

 class EAN {

    // your declarations go here

 };

 bool isValid(const char* str);

This forward declaration informs the compiler that Prefix is a valid class, which is fully defined elsewhere. 

In your EAN.cpp implementation file include the header files for your EAN and GS1Prefix modules.  Replace the function definition for your global isRegistered() function with the new definition for your member function (as described above).  Replace the function calls within isRegistered() with calls to the equivalent member functions on the Prefix object.  Retain your original definition of the global isValid() function.

Main Module

The client program posted here accepts up to 100 EANs in a single run.  It displays a menu, accepts a user selection, and completes the requested task. 

The options include:

  • Add an EAN
  • Change Style
  • View all EANs
  • Quit

If the user makes an invalid choice, this program's menu function asks for another choice. 

To change the output style, the user selects the option and then enters the character that identifies the style.

Sample Run

To compile this client program with your modules on Linux, use the command:

 g++ a2main.cpp GS1Prefix.cpp EAN.cpp

If you are using Linux, make sure that your prefix file is in the same directory as your executable.  If you are using the Visual Studio IDE, make sure that your prefix file is in the same directory as your project file. 

The output from a sample run might look something like:

 EAN Processor
 =============

 Please select from the following options :
  A - Add an EAN
  F - Change output style
  V - View all EANs
  Q - Quit
  Your selection : a

 EAN (0 to quit) : 9789070002046

 Please select from the following options :
  A - Add an EAN
  F - Change output style
  V - View all EANs
  Q - Quit
  Your selection : a

 EAN (0 to quit) : 9780003194875
 Invalid check digit. Try again.
 EAN (0 to quit) : 978000319487
 Too few characters. Try again.
 EAN (0 to quit) : 9780003194876

 Please select from the following options :
  A - Add an EAN
  F - Change output style
  V - View all EANs
  Q - Quit
  Your selection : a

 EAN (0 to quit) : 97899955000
 Too few characters. Try again.
 EAN (0 to quit) : 0
 ** No EAN added!

 Please select from the following options :
  A - Add an EAN
  F - Change output style
  V - View all EANs
  Q - Quit
  Your selection : a

 EAN (0 to quit) : 9789995500009

 Please select from the following options :
  A - Add an EAN
  F - Change output style
  V - View all EANs
  Q - Quit
  Your selection : v

               EAN
 -----------------
 978-90-70002-04-6
 978-0-00-319487-6
     9789995500009

 Please select from the following options :
  A - Add an EAN
  F - Change output style
  V - View all EANs
  Q - Quit
  Your selection : f

 EAN Style ('-', ' ', '\n' or '0' to quit) :    // enter a space here

 Please select from the following options :
  A - Add an EAN
  F - Change output style
  V - View all EANs
  Q - Quit
  Your selection : v

               EAN
 -----------------
 978 90 70002 04 6
 978 0 00 319487 6
     9789995500009

 Please select from the following options :
  A - Add an EAN
  V - View all EANs
  C - Configure the EAN display
  Q - Quit
  Your selection : q

 Signing off ...
 Press any key to continue . . .

Once your program yields the results shown above, it is ready for final testing. 


Submission

A file containing functions to test your classes is posted here.  Copy this file into your assignment directory, re-compile your class modules with this file and run the executable.

Once the executable indicates that you may submit your program, create a typescript using the following commands:

 + At the prompt, type: script a2.txt
 + At the prompt, type: whoami
 + At the prompt, type: cat GS1Prefix.h
 + At the prompt, type: cat GS1Prefix.cpp
 + At the prompt, type: cat EAN.h
 + At the prompt, type: cat EAN.cpp
 + At the prompt, type: g++ a2test.cpp GS1Prefix.cpp EAN.cpp
 + At the prompt, type: a.out
 + At the prompt, type: cat a2main.cpp GS1Prefix.cpp EAN.cpp
 + At the prompt, type: a.out
 + At each input prompt, enter the data for the sample run shown above.
 + At the prompt type: exit

These commands will produce a file named a2.txt.  Submit this file according to your professor's instructions along with any other information your professor has requested.

Assignments that are submitted after the due date will attract a 10% late penalty per school day to a maximum deduction of 50%.

If you submit an assignment that does not pass all of the tests, you will be asked to fix your code and to resubmit, in which case you will receive an assignment mark no higher than 50% of the mark allocated for this assignment.

Regardless of how long it takes you to complete this assignment, you will need to submit a completed version in order to pass this course.







  Designed by Chris Szalwinski   Copying From This Site   
Logo
Creative Commons License