My prof is touching on information hiding, and good programming techniques. He said it's a good idea to keep as much of the user interface (i.e., couts) in main, and then modify object variables through the use of functions.

Here's what I want to do:
I'm starting on a program that lets the user input the type of pizza (hand tossed, pan, deep dish), the size (s, m, l) and the toppings they want.

So far, here's what I've setup in my class:

#pragma once

#include <iostream>
using namespace std ;

const double SMALL = 10.00
const double MEDIUM = 14.00
const double LARGE = 17.00
const double TOPPING = 2.00

class Pizza
{
public:
    void set ( ) ;
    void outputDesc ( ) ;
    double computePrice ( ) ;
private:
    char type ;
    char size ;
    int toppings[7] ;
} ;

For the toppings, I figured the easiest way is to do a loop of some sort until they're finished inputting toppings (maximum of 7). The reason I'm using an array is because I have to include a function that outputs the object data, including each topping.

My question is this: How can I allow the user to input the toppings they want in main(), and then put that data into the array in my object without creating a temp array for user input?

Recommended Answers

All 38 Replies

My prof is touching on information hiding, and good programming techniques.

Good. Then don't do this:

#pragma once

#include <iostream>
using namespace std ;

Having the using namespace std basically defeats the purpose of a namespace. And putting it in the header is known to cause problems down the line.

And the #pragma once thing is platform-specific. Include guards are what I would prefer.

My question is this: How can I allow the user to input the toppings they want in main(), and then put that data into the array in my object without creating a temp array for user input?

You could pass parameters to your member functions.

For the toppings, I figured the easiest way is to do a loop of some sort until they're finished inputting toppings (maximum of 7). The reason I'm using an array is because I have to include a function that outputs the object data, including each topping.

My question is this: How can I allow the user to input the toppings they want in main(), and then put that data into the array in my object without creating a temp array for user input?

Make a member function void add_topping(int topping_number), that adds a topping. Or make an extra array. It's not like it's a big deal, to make an extra array.

And what is 'outputDesc' for? You're having a pizza class that can output its information? That violates the principle you've described. (And what is 'set', too?)

Good. Then don't do this:
Having the using namespace std basically defeats the purpose of a namespace. And putting it in the header is known to cause problems down the line.

so do like std::cout << ?

And the #pragma once thing is platform-specific. Include guards are what I would prefer.

I don't understand how to use the Include gaurds; could you explain them?

For the toppings, I figured the easiest way is to do a loop of some sort until they're finished inputting toppings (maximum of 7). The reason I'm using an array is because I have to include a function that outputs the object data, including each topping.

Make a member function void add_topping(int topping_number), that adds a topping. Or make an extra array. It's not like it's a big deal, to make an extra array.

alright, just wanted to make sure there wasn't an easier way. thanks

And what is 'outputDesc' for? You're having a pizza class that can output its information? That violates the principle you've described. (And what is 'set', too?)

I'm not sure I understand; why shouldn't I do outputDesc? I need some way of diplaying a list of information that has been input.
Set is the function that sets the values for type/size/toppings

so do like std::cout << ?

Or using std::cout;

I don't understand how to use the Include gaurds; could you explain them?

Follow that link I posted. ;)

alright, just wanted to make sure there wasn't an easier way. thanks

Early on it's more of an exercise to go through.

#include <iostream>
#include "pizza.h"

int main()
{
   pizza::topping toppings[7] = 
   { 
      pizza::sausage, pizza::mushrooms,
      pizza::none, pizza::none, pizza::none, pizza::none, pizza::none,
   };
   pizza mypie(pizza::deep_dish, pizza::medium, toppings);
   std::cout << mypie;
   return 0;
}

/* my output
Medium Deep Dish
 Sausage
 Mushrooms
*/

I did follow the link, still didn't make sense

#ifndef PIZZA_H
#define PIZZA_H

// ...

#endif

As in...

#ifndef PIZZA_H
#define PIZZA_H

#include <ostream>

class pizza
{
public:
   enum type
   {
      hand_tossed, pan, deep_dish
   };
   enum size
   {
      small, medium, large
   };
   enum topping
   {
      none, pepperoni, sausage, mushrooms, green_peppers, canadian_bacon, onions
   };
private:
   type     m_type;
   size     m_size;
   topping  m_topping[7];
public:
   pizza(type type_ = hand_tossed, size size_ = large, topping toppings_[7])
   : m_type(type_), m_size(size_)
   {
      for ( int i = 0; i < sizeof m_topping / sizeof *m_topping; ++i )
      {
         m_topping[i] = toppings_[i];
      }
   }
   friend std::ostream& operator<< (std::ostream& o, const pizza &p);
};

#endif

Each header needs it's own unique #define that you make up.

[edit]The first time you #include "pizza.h" , your macro ( PIZZA_H in this example) is not #define d, so it gets #define d and the contents #include d. Thereafter, subsequent attempts to #include this header will already have the macro ( PIZZA_H in this example) #define d, and the contents will be skipped.

Oh ok, I still don't quite get it but it's making more sense now.

is there something wrong with this part of my code? I get an error saying arrays of refrences are illegal

#include "prob7.h"

void Pizza::set ( char x , char y , int & a[7] )
{
    type = x ;
    size = y ;
    toppings = a ;
}

void Pizza::ouputDesc ( int i ) 
{
    cout << endl << "Style:  " << style << endl ;
    cout << "Size:  " << size << endl ;
    cout << "Toppings:  " << flush ;
    
    for ( int x = 0 ; x < i ; x++ )
        cout << toppings [ i ] << ", " << flush ;
}

great, but now i get an overloaded function error on the same function.

prototype: void set ( char , char , int ) ;

Are you saying that the function's prototype does not match its definition? You need to have the corresponding change in both places.

they match:

prototype:

void set ( char , char , int & , int ) ;

function:

void Pizza::set ( char x , char y , int (&a)[7] , int i )
{
    type = x ;
    size = y ;
    for ( int x = 0 ; x < i ; x++ )
    toppings[i] = a[i] ;
}

call:

pizza.set ( x , y , a[6] , i ) ;

edit]: I haven't used arrays since last year, so forgive my ignorance on them for now :(

No. They don't match. All three would appear to be different. There is no harm in naming parameters in a prototype. Otherwise you could do something icky-looking like int (&)[7] . It's not a reference to an int , it's a reference to an array of int .

ah wonderful!

I'm getting closer, but i need your help yet again.

Do you see the logic error in this part of my code?

edit]: stupid mistake; code deleted

else if ( answer == 'y' || answer == 'Y' )
    {
        cout << "How many toppings would you like (maximum of 7)?" << endl ;
        cin >> i ;
        cout << "Please choose from the following list:  " << endl ;
        cout << "\t1. Extra Pepperoni \t2. Extra Cheese" << endl ;
        cout << "\t3. Sausage         \t4. Jalapenos" << endl ;
        cout << "\t5. Banana Peppers  \t6. Green Peppers" << endl ;
        cout << "\t7. Mushrooms       \t8. M&Ms" << endl ;
        cout << "Enter " << i << " topping numbers, followed by the 'Enter' key:  " << endl ;
        for ( i = 0 ; i < 7 ; i++ )
        {
            cin >> a[i] ;
        }
    }

am i doing something wrong here?
I only want to input the specified number into the array but it's making me input data for the entire array before moving on.

cin >> i ;
        // ...
        cout << "Enter " << i << " topping numbers, followed by the 'Enter' key:  " << endl ;
        for ( i = 0 ; i < 7 ; i++ )

Between hither and yon, you discard the value entered and hard-code the loop for all 7. You need a loop variable to count to the value entered (or else decrement the counter -- but that gets to be more work).

so i just tested my code again; thanks for the help btw !

here's what i got, lol:

Please choose from the following list:
        1. Extra Pepperoni      2. Extra Cheese
        3. Sausage              4. Jalapenos
        5. Banana Peppers       6. Green Peppers
        7. Mushrooms            8. M&Ms
Enter 2 topping numbers, followed by the 'Enter' key:
3
2
Thank you
Order Description:

Style:  ☻
Size:  s
Toppings:  1310720, 1310720, Press any key to continue . . .

a smiley face? ha!

So I would like to output the toppings they chose instead of well... in this case the address in memory.
But even if it output the correct number, i would like to have some way to say if it's a 1 output this if it's a 2 output this etc.
any suggestions? can you do a switch on an array?

Using a char as a small int ?

// pizza.cpp
#include "pizza.h"

std::ostream& operator<< (std::ostream& o, const pizza &p)
{
   switch ( p.m_size )
   {
   case pizza::small:  o << "Small ";  break;
   case pizza::medium: o << "Medium "; break;
   case pizza::large:  o << "Large ";  break;
   }
   switch ( p.m_type )
   {
   case pizza::deep_dish:   o << "Deep Dish\n";   break;
   case pizza::hand_tossed: o << "Hand-Tossed\n"; break;
   case pizza::pan:         o << "Pan\n";         break;
   }
   for ( int i = 0; i < sizeof p.m_topping / sizeof *p.m_topping; ++i )
   {
      switch ( p.m_topping[i] )
      {
      case pizza::none: break;
      case pizza::pepperoni:       o << " Pepperoni\n";      break;
      case pizza::sausage:         o << " Sausage\n";        break;
      case pizza::mushrooms:       o << " Mushrooms\n";      break;
      case pizza::green_peppers:   o << " Green Peppers\n";  break;
      case pizza::canadian_bacon:  o << " Canadian Bacon\n"; break;
      case pizza::onions:          o << " Onions\n";         break;
      }
   }
   return o;
}

Just for ideas.

commented: excellent help; sorry for taking so much of your time! much appreciated, thanks agian!! +4

Ok i tried to do what you did and i failed.
=(

void Pizza::outputDesc ( int i ) 
{
    cout << endl << "Style:  " << type << endl ;
    cout << "Size:  " << size << endl ;
    cout << "Toppings:  " << flush ;
    
    for ( int x = 0 ; x < i ; x++ )
   {
      switch ( toppings[x] )
      {
      case 1:        cout << "Extra Pepperoni\n" ;            break ;
      case 2:        cout << "Extra Cheese\n" ;                break ;
      case 3:        cout << "Extra Sausage\n" ;                break ;
      case 4:        cout << "Extra Jalapenos\n" ;            break ;
      case 5:        cout << "Extra Banana Peppers\n" ;        break ;
      case 6:        cout << "Extra Green Peppers\n" ;        break ;
      case 7:        cout << "Extra Mushrooms\n" ;            break ;
      case 8:        cout << "M&Ms\n" ;                        break ;
      }
   }
}

thanks for all this help; i really appreciate it

did you always have 3 rep blocks or did i just do that?

Ok i tried to do what you did and i failed.

Can you better describe "failed"?

With regard to the char / int thing I mentioned, a char with a value of 1 is (likely) not the same as a char with a value of '1' -- and they are printed differently (perhaps a smiley).

For what looked like pointer values being printed earlier, we may need to see more code.

Alright, I'll post my whole code so far.
I haven't done the #include guard thing you mentioned, since i don't fully understand it. Perhaps if you could modify my code a bit and repost it, I will grasp it better. Even with that, I don't fully understand the concept behind it.

If you happen to notice [I]any[/I] poor techniques in my coding do not hesitate to point it out! Even though my focus is in networking, I can't seem to get enough of programming lately. Once school started, I became addicted again! haha

header file:

#pragma once

#include <iostream>
using std::cout ;
using std::cin ;
using std::endl ;
using std::flush ;

const double SMALL = 10.00 ;
const double MEDIUM = 14.00 ;
const double LARGE = 17.00 ;
const double TOPPING = 2.00 ;

class Pizza
{
public:
    void set ( char x , char y , int (&a)[6] , int i ) ;
    void outputDesc ( int ) ;
    double computePrice ( ) ;
private:
    char type ;
    char size ;
    int toppings[7] ;
} ;

functions:

#include "prob7.h"

void Pizza::set ( char x , char y , int (&a)[6] , int i )
{
    type = x ;
    size = y ;
    for ( int x = 0 ; x < i ; x++ )
    toppings[i] = a[i] ;
}

void Pizza::outputDesc ( int i ) 
{
    cout << endl << "Style:  " << type << endl ;
    cout << "Size:  " << size << endl ;
    cout << "Toppings:  " << flush ;

    for ( int x = 0 ; x < i ; x++ )
   {
      switch ( toppings[x] )
      {
      case 1:        cout << "Extra Pepperoni\n" ;            break ;
      case 2:        cout << "Extra Cheese\n" ;                break ;
      case 3:        cout << "Extra Sausage\n" ;                break ;
      case 4:        cout << "Extra Jalapenos\n" ;            break ;
      case 5:        cout << "Extra Banana Peppers\n" ;        break ;
      case 6:        cout << "Extra Green Peppers\n" ;        break ;
      case 7:        cout << "Extra Mushrooms\n" ;            break ;
      case 8:        cout << "M&Ms\n" ;                        break ;
      }
   }
}

main:

#include "prob7.h"

int main ( )
{
    Pizza pizza ;

    char x ;
    char y ;
    int a[ 6 ] ;
    int i ;

    char answer ;

    cout << "How would you prefer your pizza be cooked?  " << endl ;
    cout << "Available Options:  " << endl ;
    cout << "\tHand Tossed" << endl ;
    cout << "\tPan" << endl ;
    cout << "\tDeep Dish" << endl ;
    cout << "Selection:  " << flush ;
    cin >> x ;

    cout << "What size would you prefer? " << endl ;
    cout << "Available Options:  " << endl ;
    cout << "\tSmall" << endl ;
    cout << "\tMedium" << endl ;
    cout << "\tLarge" << endl ;
    cout << "Selection:  " << flush ;
    cin >> y ;

    cout << "Would you like to add additional toppings ($2.00/ea)?" << flush ;
    cin >> answer ;

    if ( answer != 'y' && answer != 'Y' && answer != 'n' && answer != 'N' )
    {
        cout << "Invalid answer - Exiting program because I'm too lazy to do ECC" << endl ;
        exit ( 1 ) ;
    }
    else if ( answer == 'y' || answer == 'Y' )
    {
        cout << "How many toppings would you like (maximum of 7)?" << endl ;
        cin >> i ;
        cout << "Please choose from the following list:  " << endl ;
        cout << "\t1. Extra Pepperoni \t2. Extra Cheese" << endl ;
        cout << "\t3. Sausage         \t4. Jalapenos" << endl ;
        cout << "\t5. Banana Peppers  \t6. Green Peppers" << endl ;
        cout << "\t7. Mushrooms       \t8. M&Ms" << endl ;
        cout << "Enter " << i << " topping numbers, followed by the 'Enter' key:  " << endl ;
        for ( x = 0 ; x < i ; x++ )
        {
            cin >> a[i] ;
        }
    }

    pizza.set ( x , y , (&a)[6] , i ) ;

    cout << "Thank you" << endl ;
    cout << "Order Description:  " << endl ;
    pizza.outputDesc ( i ) ;

    return 0 ;
}
int type ;
void set ( char x , char y , int (&a)[7] , int i ) ;
void Pizza::set ( char x , char y , int (&a)[7] , int i )
int a[ 7 ] ;
cin >> a[x] ;
toppings[x] = a[x] ;

[edit=2]

How would you prefer your pizza be cooked?  
Available Options:  
	Hand Tossed
	Pan
	Deep Dish
Selection:  1
What size would you prefer? 
Available Options:  
	Small
	Medium
	Large
Selection:  2
Would you like to add additional toppings ($2.00/ea)?y
How many toppings would you like (maximum of 7)?
2
Please choose from the following list:  
	1. Extra Pepperoni 	2. Extra Cheese
	3. Sausage         	4. Jalapenos
	5. Banana Peppers  	6. Green Peppers
	7. Mushrooms       	8. M&Ms
Enter 2 topping numbers, followed by the 'Enter' key:  
3
7
Thank you
Order Description:  

Style:  2
Size:  2
Toppings:  Extra Sausage
Extra Mushrooms

[/edit]
[edit]Nothing in the header needs these:

#include <iostream>
using std::cout ;
using std::cin ;
using std::endl ;
using std::flush ;

They may be better placed in the cpp files.

Alright, i have one error now.

1>.\prob7.main.cpp(54) : error C2664: 'Pizza::set' : cannot convert parameter 3 from 'int' to 'int []'

at this line

pizza.set ( x , y , a[7] , i ) ;

class:

void set ( int x , int y , int a[7] , int i ) ;

declaration:

void Pizza::set ( int x , int y , int a[7] , int i )

at this line pizza.set ( x , y , a[7] , i ) ;

a[7] is an element in your array
(Also - if your array is only 7 elements in size, then valid elements are indexed 0-6, so you're accessing one-past-the-end.)

try this instead pizza.set ( x , y , a, i ) ;

commented: thanks for the help +4
commented: Thanks. I had made that change but forgot to post it. +11

ah, thanks!

crap now i get this error

1>.\prob7.func.cpp(10) : error C2109: subscript requires array or pointer type

void Pizza::set ( int x , int y , int a , int i )
{
    type = x ;
    size = y ;
    for ( int z = 0 ; z < i ; z++ )
    toppings[z] = a[z] ;
}

yeah i can't figure it out, i'm giong to have to wait on one of yo uguys to help me... =\

thanks in advance

void Pizza::set ( int x , int y , int a , int i )

Does this match your prototype?

yes

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.