Help me please!!!

This is a discussion on Help me please!!! within the C++ Programming forums, part of the General Programming Boards category; I am now dissecting each file piece by piece. The project consists of 2 header files and 2 definition files ...

  1. #1
    Registered User
    Join Date
    Jul 2004
    Posts
    61

    Help me please!!!

    I am now dissecting each file piece by piece. The project consists of 2 header files and 2 definition files plus a main program utilizing both classes. One of the definition files (sales.cpp) compiles fine, the other one (register.cpp) is the one that produces 2 errors. I am going to provide the 2 header files that are needed to be included in the register.cpp, as well as the register.cpp file. Any help that can be given I will appreciate immensely.

    sale.h
    Code:
        enum ItemType {BOOK, DVD, SOFTWARE, CREDIT};
    
    class Sale
    {
    public:
       Sale();			// default constructor, 
    				// sets numerical member data to 0
    
       void MakeSale(ItemType x, double amt);	
    
    	// the MakeSale function loads data into the Sale object.  The
    	// item and price are passed in.  Compute tax and total.
    	// (For store credits, tax is 0).
    
       ItemType Item();		// Returns the type of item in the sale
       double Price();		// Returns the price of the sale
       double Tax();		// Returns the amount of tax on the sale
       double Total();		// Returns the total price of the sale
       void Display();		// outputs sale info (described below)
    
      // for the Display function, output the sale item, the price, the tax,
      // and the total (all on one line).  For store credit, the amounts
      // should be enclosed in < > symbols, to indicate a negative charge.  
      // All monetary output should be in dollars and cents format, to two
      // decimal places. 
      // Examples:	Book         $ 20.00    Tax:  $ 1.40   Total:  $ 21.40
      //		Credit	    <$ 15.00>   Tax:  $ 0.00   Total: <$ 15.00>
    
    private:
       double price;	// price of item or amount of credit
       double tax;		// amount of sales tax (does not apply to credit)
       double total;	// final price once tax is added in.
       ItemType item;	// transaction type
    };
    register.h
    Code:
       //register header file
    
    #include "sale.h"
    
    class Register
    {
    public:
       Register(int i, double amt);//allows ID number and starting amount
                                  //in register to be initialized when
                                  //object is created
    
       int GetID();//returns current ID number in the register to the
                   //caller, accessor function
    
       double GetAmount();//return current amount in the register to
                   //caller, accessor function
    
    
       void RingUpSale(ItemType c, double amt);//stores sale in sale list
                                              //also updates money amount
                                              //in register.
                                              //allows item type and sale
                                              //base price to be passed in
    
       void ShowLast();//displays only the info about last sale made
    
       void ShowAll();//Shows all of sales currently in sale list, one per line
    
       void Cancel();//cancels last sale in list
    
       double SalesTax(int n);//calculates and returns total amount of sales tax
                               //for last n sales (i.e. most recent ones)
    
       private:
         int ID;
         double Amount;
         double sales_taxxx;
         double base_price;
    	 int numsales;
    
    	 Sale *sales;
    };
    register.cpp
    Code:
        //definitions for register class
    
    #include <iomanip>
    #include <iostream>
    
    #include "Register.h"
    #include "sale.h"
    
    
    
    using namespace std;
    
    //Register definitions
    
    Register::Register(int i, double amt)
    {
        ID=i;
        Amount=amt;
    	numsales=0;
        //parameters in register are intialized to 0
    }
    
    int Register::GetID()
    {
        return ID;//returning current ID in register
    }
    
    double Register::GetAmount()
    {
        return Amount;//returning current amount in refrigerator
    }
    
    void Register::RingUpSale(ItemType c, double amt)
    {
    	Sale *s;
    
    	//create a new array
    	//memcpy the old array into the new array byte by byte
    	//set the old array to the new array.
    	
    
    	numsales++;
    	s = new Sale[numsales];
    	memcpy(s, sales, sizeof(Sale)*(numsales-1));	
    	s[numsales-1].MakeSale(c, amt);
    	sales=s;
    
    	if (c==CREDIT) {
    		Amount-=amt;
    	               } 
        else {
    		Amount+=amt;
    	     }
    
    }
    
    
    void Register::ShowAll(void) {
    
    	if (numsales==0) { 
          cout<<"No Sales Have Been Made Silly...."; 
          return;   
                         }
    
    	for (int i=0;i<numsales;i++) {
    		sales[i].Display();
    		
    
    	                              }
    
    
    
    
    
                                  }
    
    void Register::ShowLast(void) {
    	if (numsales==0) { 
        cout<<"No Sales Have Been Made Silly...."; 
        return; 
                          }
    	
    	sales[numsales-1].Display();
    
    
                                   }
    
    
    void Register::Cancel(void) {
    {
    	Sale *s;
    
    	if (numsales==0) { 
        cout<<"No Sales Have Been Made Silly...."; 
        return; 
                         }
    
    	//create a new array
    	//memcpy the old array into the new array byte by byte
    	//set the old array to the new array.
    	
    	if (s[numsales].Item()==CREDIT) {
    		Amount+=s[numsales].Price();
    	                                } 
            else {
    		Amount-=s[numsales].Price();
    	         }
    
    
    	numsales--;
    
    	s = new Sale[numsales];
    	memcpy(s, sales, sizeof(Sale)*(numsales));	
    
    	sales=s;
    
    
    }
    
    
     
                         }
    
    
    
    double Register::SalesTax(int n) {
    int t_n=0;
    double tax_total=0;
    
    
    if (n<0) {
        cout<<"Invalid Number..."<<endl; 
        return 0;
             }
    
    
    //figure out how many to count
    if (n > numsales) {
    	t_n=numsales;
                      } 
       else {
    	t_n=n;
            }
    
    
    //count t_n recent items
    for (int i=(numsales-1);i>=(numsales-t_n);i--)
    	tax_total+=sales[i].Tax();	
    
    
    return tax_total;
                                      }
    Code:
    Compiler errors:
    Code:
    
        sale.h(14) : error C2011: 'ItemType' : 'enum' type redefinition
        sale.h(17) : error C2011: 'Sale' : 'class' type redefinition

  2. #2
    Software Developer jverkoey's Avatar
    Join Date
    Feb 2003
    Location
    University of Waterloo
    Posts
    1,904
    dantestwin, let me introduce you to a couple of my friends, #ifndef, #define, and #endif. These friends are very nice and allow you to be much more friendly with your compiler so that it won't yell it you for not knowing enough people.

    But enough metaphorical junk.

    What's happening here is this: you are including sale.h twice, meaning it is defining everything inside of the file twice, causing the error.

    Here's where our friends come in.

    It is good practice that in most .h files that you make to have this sort of syntax:
    Let's say we have a class named catastrophe, k?

    catastrophe.h
    Code:
      #ifndef CATASTROPHE_H_
      #define CATASTROPHE_H_
      
      enum CatastropheTypes
      { METEORITE, LAPTOP_KEYBOARD_MALFUNCTION, CAR_CRASH, CAT_PUKING_ON_MAIL, UNIVERSE_IMPLODING };
      
      class catastrophe
      {
      private:
      	unsigned int totalDestruction;
      	double cost;
      	int occurring;
      	int catType;
      public:
      	void start(int type);
      	void end();
      	int process();
      
      	int isHappening();
      	int getType();
      };
      
      #endif
    and say we've got some world code:

    world.cpp
    Code:
      #include "catastrophe.h"
      #include <stdio.h>
      #include "universeDefs.h"
      
      int main()
      {
      	catastrophe worldCat;
      
      	worldCat.start(LAPTOP_KEYBOARD_MALFUNCTION);
      
      	int worldIsAlive=1;
      
      	while(worldIsAlive && worldCat.isHappening())
      	{
      	    worldIsAlive=worldCat.process();
      	}
      
      	StartUniverseCat();
      	worldCat.end();
      
      	while(RunUniverse());
      
      	printf("The world has ended and the universe imploded....  I guess I'll ttyl\n");
      
      	return 0;
      }
    and now let's say we've got another cpp file in the project that processes the universe:

    universe.cpp
    Code:
      #include "catastrophe.h"
      #include "universeDefs.h"
      
      catastrophe uniCat;
      
      void StartUniverseCat()
      {
      	uniCat.start(UNIVERSE_IMPLODING);
      }
      
      int RunUniverse()
      {
      	return uniCat.process();
      }
    and now we need our universeDefs.h file for the function prototypes:

    universeDefs.h
    Code:
      #ifndef UNIVERSEDEFS_H_
      #define UNIVERSEDEFS_H_
      
      void StartUniverseCat();
      int RunUniverse();
      
      #endif
    ok, so we've got tons of fun code, don't ask why I just wrote all that, cuz I won't answer.

    Anyways, the point being here is notice how world.cpp and universe.cpp both include catastrophe.h, right? However, because of the #ifndef/#define/#endif surrounding our headers, the enumeration will not be redefined because when the precompiler sees those statements the first time it goes:
    precompiler: "Is CATASTROPHE_H_ already defined?"
    precompiler checks if it's defined
    precompiler: "Nope, define it then and keep reading"

    then the next time it reads it it goes:
    precompiler: "Is CATASTROPHE_H_ already defined?"
    precompiler checks if it's defined
    precompiler: "Yup, I'm going to skip reading most of the things until I hit the #endif at the end of the file, making me miss any redefinitions that might have happened"

    But yah, #ifndef #define #endif are very useful tools, I hope I helped out at least somewhat

    I'm going to go back to.....wait....I have nothing else to do...oh yah

    -edit-
    I have no idea if that code works or not, I didn't implement the catastrophe class, but it would be funny if those implementations were the only errors, cuz I just typed all that code in these stupid tiny edit boxes for replying....*tries to push the edges of the text box so he can fit more than 7 words on one line*.....*fails*

  3. #3
    Software Developer jverkoey's Avatar
    Join Date
    Feb 2003
    Location
    University of Waterloo
    Posts
    1,904
    oh, and here's the shortened version of the post above, before people flip out on me:

    take your sale.h file and add this to the top of the file:

    Code:
     #ifndef SALE_H_
     #define SALE_H_
    and add this to the bottom of the file, after all of the code

    Code:
     #endif

  4. #4
    Registered User
    Join Date
    Jul 2004
    Posts
    61
    Ok, I added the statements you gave me to my sale.h file and now I get 2 Linker errors and 1 warning. What you said helped immensely and I'm sorry to be a pain. I'm a novice at programming and am just a bit behind the times is all. Here is the edited code.

    Code:
       #ifndef SALE_H_
     #define SALE_H_
    enum ItemType {BOOK, DVD, SOFTWARE, CREDIT};
    
    class Sale
    {
    public:
       Sale();			// default constructor, 
    				// sets numerical member data to 0
    
       void MakeSale(ItemType x, double amt);	
    
    	// the MakeSale function loads data into the Sale object.  The
    	// item and price are passed in.  Compute tax and total.
    	// (For store credits, tax is 0).
    
       ItemType Item();		// Returns the type of item in the sale
       double Price();		// Returns the price of the sale
       double Tax();		// Returns the amount of tax on the sale
       double Total();		// Returns the total price of the sale
       void Display();		// outputs sale info (described below)
    
      // for the Display function, output the sale item, the price, the tax,
      // and the total (all on one line).  For store credit, the amounts
      // should be enclosed in < > symbols, to indicate a negative charge.  
      // All monetary output should be in dollars and cents format, to two
      // decimal places. 
      // Examples:	Book         $ 20.00    Tax:  $ 1.40   Total:  $ 21.40
      //		Credit	    <$ 15.00>   Tax:  $ 0.00   Total: <$ 15.00>
    
    private:
       double price;	// price of item or amount of credit
       double tax;		// amount of sales tax (does not apply to credit)
       double total;	// final price once tax is added in.
       ItemType item;	// transaction type
    };
    #endif
    And this is what the compiler tells me.
    Code:
      warning C4700: local variable 's' used without having been initialized
    Linking...
    LIBCD.lib(wincrt0.obj) : error LNK2001: unresolved external symbol _WinMain@16
    Debug/friggen.exe : fatal error LNK1120: 1 unresolved externals

  5. #5
    Super Moderator
    Join Date
    Sep 2001
    Posts
    4,913
    Is this the same project that's been in the last 3 threads?

  6. #6
    Registered User
    Join Date
    Jul 2004
    Posts
    61
    Yes. I apologize for that. I'm desperate for help.

  7. #7
    Registered User
    Join Date
    Mar 2004
    Posts
    113
    where r u defining the member functions of class Sale?,
    sorry i'm slow today

  8. #8
    Registered User
    Join Date
    Jul 2004
    Posts
    61
    I'm defining them using these 2 files:

    sale.cpp
    Code:
       //definitions for Sales.h
    
    #include <iostream>
    #include "sale.h"
    #include <iomanip>
    #include <cctype>
    
    using namespace std;
    
    Sale::Sale()
    {
         
    price=0.0;
    tax=0.0;
    total=0.0;
           
    }
    
    void Sale::MakeSale(enum ItemType x, double amt)
    {
    item=x;
    price=amt;
    if (item==CREDIT)
         {
           tax=0.0;
           total=price;
           return;
         }
         
    tax= price *.07;
    total= price +tax;
    }
           
    ItemType Sale::Item()
    {
    
    return item;
    }
    
    double Sale::Price()
    {
    
    return price;
    }
    
    double Sale::Tax()
    {
    return tax;
    
    }
    
    double Sale::Total()
    {
    
    return total;
    
    }
    
    void Sale::Display()
    {
    //return everything else, display simply displays
    if (item==BOOK)
    cout<<"Book\t"<<price<<"\tTax:\t"<<tax<<"\tTotal:\t"<<total<<endl;
    
    if (item==DVD)
    cout<<"DVD\t"<<price<<"\tTax:\t"<<tax<<"\tTotal:\t"<<total<<endl;
    
    if (item==SOFTWARE)
    cout<<"Software\t"<<price<<"\tTax:\t"<<tax<<"\tTotal:\t"<<total<<endl;
    
    if (item==CREDIT)
    cout<<"Credit \t"<< "<"<<price<<">"<<"\tTax:\t"<<tax<<"\tTotal:\t"<<"<"<<total<<endl;
    
    }
    register.cpp
    Code:
       //definitions for register class
    
    #include <iomanip>
    #include <iostream>
    
    #include "Register.h"
    #include "sale.h"
    
    
    
    using namespace std;
    
    //Register definitions
    
    Register::Register(int i, double amt)
    {
        ID=i;
        Amount=amt;
    	numsales=0;
        //parameters in register are intialized to 0
    }
    
    int Register::GetID()
    {
        return ID;//returning current ID in register
    }
    
    double Register::GetAmount()
    {
        return Amount;//returning current amount in refrigerator
    }
    
    void Register::RingUpSale(ItemType c, double amt)
    {
    	Sale *s;
    
    	//create a new array
    	//memcpy the old array into the new array byte by byte
    	//set the old array to the new array.
    	
    
    	numsales++;
    	s = new Sale[numsales];
    	memcpy(s, sales, sizeof(Sale)*(numsales-1));	
    	s[numsales-1].MakeSale(c, amt);
    	sales=s;
    
    	if (c==CREDIT) {
    		Amount-=amt;
    	               } 
        else {
    		Amount+=amt;
    	     }
    
    }
    
    
    void Register::ShowAll(void) {
    
    	if (numsales==0) { 
          cout<<"No Sales Have Been Made Silly...."; 
          return;   
                         }
    
    	for (int i=0;i<numsales;i++) {
    		sales[i].Display();
    		
    
    	                              }
    
    
    
    
    
                                  }
    
    void Register::ShowLast(void) {
    	if (numsales==0) { 
        cout<<"No Sales Have Been Made Silly...."; 
        return; 
                          }
    	
    	sales[numsales-1].Display();
    
    
                                   }
    
    
    void Register::Cancel(void) {
    {
    	Sale *s;
    
    	if (numsales==0) { 
        cout<<"No Sales Have Been Made Silly...."; 
        return; 
                         }
    
    	//create a new array
    	//memcpy the old array into the new array byte by byte
    	//set the old array to the new array.
    	
    	if (s[numsales].Item()==CREDIT) {
    		Amount+=s[numsales].Price();
    	                                } 
            else {
    		Amount-=s[numsales].Price();
    	         }
    
    
    	numsales--;
    
    	s = new Sale[numsales];
    	memcpy(s, sales, sizeof(Sale)*(numsales));	
    
    	sales=s;
    
    
    }
    
    
     
                         }
    
    
    
    double Register::SalesTax(int n) {
    int t_n=0;
    double tax_total=0;
    
    
    if (n<0) {
        cout<<"Invalid Number..."<<endl; 
        return 0;
             }
    
    
    //figure out how many to count
    if (n > numsales) {
    	t_n=numsales;
                      } 
       else {
    	t_n=n;
            }
    
    
    //count t_n recent items
    for (int i=(numsales-1);i>=(numsales-t_n);i--)
    	tax_total+=sales[i].Tax();	
    
    
    return tax_total;
                                      }
    main program
    Code:
    #include "sale.h"
    #include "Register.h"
    
    #include <iostream>
    
    void main(void) {
    
    
    using namespace std;
    char command;
    char stype;
    ItemType saletype;
    double bprice;
    int pastitemstotax;
    
    
    
    Register r(1234, 10.00);
    
    r.RingUpSale(SOFTWARE, 1.00);//passing in item type and sale base price
    r.RingUpSale(DVD, 2.00);
    r.RingUpSale(BOOK, 3.00);
    
    
    cout<<"Jessica's Register: Enter Command: ";
    cin>>command;
    
    if (command<97) {command+=32;}//character setting
    
    
    
    
    
    while (command != 'x') {//error checking
    
    	if (command=='s') {
    
    		cout<<"Current ID     : "<<r.GetID()<<endl;//requesting current id
    		cout<<"Current Balance: "<<r.GetAmount()<<endl<<endl;//requesting current
    		                                                    //amount in register
    	                   }
    
    	if (command=='l') {
    		r.ShowAll();//requesting all current sales in register
    	                  }
    	if (command=='d') {
    		r.ShowLast();//requesting info about last sale made
    	                  }
    
    	if (command=='m') { //requesting menu
    	
    		cout<<"----------------------Menu-------------------------"<<endl;
    		cout<<"    S:   Show Current Amount in Register"<<endl;
    		cout<<"    R:   Ring Up A Sale                 "<<endl;
    		cout<<"    D:   Display the Last Sale          "<<endl;
    		cout<<"    L:   Display the Entire Sale List   "<<endl;
    		cout<<"    C:   Cancel the Last Stored Sale    "<<endl;
    		cout<<"    T:   Find the Total Sales Tax for Recent Sales"<<endl;
    		cout<<"    M:   Show This Menu                 "<<endl;
    		cout<<"    X:   Exit the Program               "<<endl;
    		cout<<"---------------------------------------------------"<<endl;
    
    
    
    	                 }
    	
    	if (command=='r') { //ringing up a sale
    		
    		stype='0';//sale type
    
    		while (stype!='b' && stype!='d' && stype!='s' && stype!='c')  {
    			cout<<"Enter Sale Type: (B - Book, D - DVD, S - Software, C - Credit)";
    			cin>>stype;
    			if (stype<97) {stype+=32;}//character setting
    		
    			if ((stype!='b' && stype!='d' && stype!='s' && stype!='c')) {
    				cout<<"Invalid Sale Type. Please ReEnter."<<endl;
                                                                            }
    
                                                                          }
    
    		
    		bprice=0;
    		cout<<endl<<"Enter Base Price: $";
    		cin>>bprice;
    
    		while (bprice<0) {
    		cout<<"Error: Base Price < 0 "<<endl<<endl<<"ReEnter Base Price: $";
    		cin>>bprice;
    		                 }
    		
    	
    		if (stype=='s') { 
              saletype=SOFTWARE;
                            }
    		if (stype=='b') { 
              saletype=BOOK;
                            }
    		if (stype=='d') { 
              saletype=DVD;
                            }
    		if (stype=='c') { 
              saletype=CREDIT;
                            }
    	
    		
    		r.RingUpSale(saletype, bprice);	//asking for storage of sale
                                            //and update of money in register	
    		
            r.ShowLast();//requesting info on last sale
    
    	                        }
    
    
    	if (command=='c') {
    
    		r.Cancel();//voids out last transaction
    		cout<<"Last Sale Cancelled..."<<endl<<endl;
    
    	                  }
    
    
    
    	if (command=='t') {
    		cout<<"Enter Past Items to Calculate Tax:";
    		cin>>pastitemstotax;
    		while ((pastitemstotax)<0) {
    			cout<<"Invalid Number..."<<endl;
    			cin>>pastitemstotax;
    		                           }
    
    
    		r.ShowAll();
    		cout<<endl<<endl;
    		cout<<r.SalesTax(pastitemstotax);
    	                    }
    
    
    
    
    cout<<endl<<endl;
    cout<<"Jessica's Register: Enter Command: ";
    cin>>command;
    if (command<97) {command+=32;}//character setting
       
                    }//end while
    
                   }//end main

  9. #9
    Software Developer jverkoey's Avatar
    Join Date
    Feb 2003
    Location
    University of Waterloo
    Posts
    1,904
    you are compiling the project as a windows executable. Therefor it is looking for the WinMain entry point (function). Create a new "Console Program" project and add your source code to that one.

  10. #10
    Registered User
    Join Date
    Jul 2004
    Posts
    61
    Thanks for your help Joe. Appreciate it.

  11. #11
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,824
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

Popular pages Recent additions subscribe to a feed

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21