0

Trying to create a program that takes a coffee flavor add-in and checks if it's valid using an array.
If valid it uses the array index to gather price information.

I managed to write the code below, but it only works for 1 iteration.
How can alter it so a user can enter: Cream and cinnamon and output the total of each add-in as well as the total price of the cup of coffee? The cup of coffee starts with a base price of $2.00

#include <iostream>
#include <string>

using namespace std;

int main()
{
    // Declare variables.
    string addIn;               // Add-in ordered
    const int NUM_ITEMS = 5;    // Named constant

    // Initialized array of add-ins
    string addIns[] = { "Cream", "Cinnamon", "Chocolate", "Amaretto", "Whiskey" };
    // Initialized array of add-in prices
    double addInPrices[] = { .89, .25, .59, 1.50, 1.75 };

    bool foundIt = false;        // Flag variable
    int x;                       // Loop control variable
    double orderTotal = 2.00;    // All orders start with a 2.00 charge
    string QUIT = "XXX";

    // Get user input
    cout << "Enter coffee add-in or XXX to quit: ";
    cin >> addIn;

    // Write the rest of the program here.
    for (x = 0; x < NUM_ITEMS && foundIt == false && addIn != QUIT; x++) {
        if (addIn == addIns[x]) {
            foundIt = true;
            x--;
        }
    }
    if (foundIt == true) {
        cout << addIns[x] << " $" << addInPrices[x] <<endl;
        cout << "$" << orderTotal + addInPrices[x] <<endl;
    }
    else {
        cout << "Sorry, we do not carry that." <<endl;
        cout << "Order total is $ " << orderTotal <<endl;
    }

    return 0;
}
Jorengarenar
  • 2,705
  • 5
  • 23
  • 60
Leo
  • 51
  • 6
  • 2
    This is a good time to step through the code with the debugger. – Michael Chourdakis Sep 23 '21 at 03:32
  • Consider wrapping the body of the function in yet another loop, that loops as long as addIn != QUIT. This extra loop would start before you declare `foundIt` and ends right before the end of main. (You can omit the return entirely.) – Chris Uzdavinis Sep 23 '21 at 03:36
  • Are you asking the user to type in `Cream and Cinnamon` ? Or do you want the user to first type `Cream`, then `Cinnamon`? – Alan Sep 23 '21 at 03:42
  • No and just cream: enter, cinnamon: enter, – Leo Sep 23 '21 at 04:07

3 Answers3

1

Don't use parallel arrays - you will mess up maintaining them.

Better options:

Create a struct for your add-ins:

struct Addin {
  std::string name;
  double price;
}

and use an array (or better yet an std::vector) of those structs.

Another option is to use a map:

std::map<std::string, double> addIns = {
    {"Cream", .89},
    {"Cinnamon", .25},
    // etc.
};

Then you won't need a loop, just a lookup

auto item = addIns.find(addIn);
if(item != addIns.end() {
  // do your math here
}
Vlad Feinstein
  • 10,960
  • 1
  • 12
  • 27
  • Thanks, I'm still a newb so I'll have to get back to this as I learn these more advanced concepts. Appreciate the help – Leo Sep 23 '21 at 03:50
  • Not really an answer to his question, but I thought of something similar too. instead of name as a key use an unsigned int, then you can present choices like 1: Cream .89, 2: Cinnamon etc.. then user only has to input numbers instead of number and there will be less chance of invalid input too – Pepijn Kramer Sep 23 '21 at 03:51
0

The structure you are looking for is a while or do/while loop. To be able to enter "empty" lines use std::getline from.

The structure of your program will then look something like this : As you can see I have a habit of changing my boolean expressions into functions (predicates). This makes code more readable and predicates reusable in other bits of code.

#include <iostream>
#include <string>

bool is_quit(const std::string& input)
{
    return input.length() > 0;
}

bool is_valid_input(const std::string& input)
{
    return true; // your own check
}

int main()
{
    bool quit = false;
    std::string input;

    do
    {
        std::cout << "give input : ";
        std::getline(std::cin, input);

        quit = is_quit(input);
    
        if (is_valid_input(input) && !quit)
        {
            std::cout << "ok" << std::endl;
        }

    } while (!quit);

    return 0;
}
Pepijn Kramer
  • 9,356
  • 2
  • 8
  • 19
0

Your program is written to get a single output. For multiple outputs there have to be loops and the not found condition also has to be re-written.

try this

#include <iostream>
#include <string>

using namespace std;

int main()
{
    // Declare variables.
             
    const int NUM_ITEMS = 5;        // Named constant
    string addIn[NUM_ITEMS];        // Add-in ordered

    // Initialized array of add-ins
    string addIns[] = { "Cream", "Cinnamon", "Chocolate", "Amaretto", "Whiskey" };
    // Initialized array of add-in prices
    double addInPrices[] = { .89, .25, .59, 1.50, 1.75 };

    //bool foundIt = false;        // Flag variable
    int x, i, j;                       // Loop control variable
    double orderTotal = 2.00;    // All orders start with a 2.00 charge
    string QUIT = "XXX";

    // Get user input
    cout << "Enter coffee add-ins followed by XXX to quit: ";
    for(i=0; i<NUM_ITEMS; i++) {
        cin >> addIn[i];
        if(addIn[i] == QUIT) {
            i++;
            break;
        }
    }

    int foundIt[i];

    // Write the rest of the program here.
    
    for(j=0; j<i; j++) {
        foundIt[j] = -1;
        for(x = 0; x<NUM_ITEMS && foundIt[j] == -1 && addIn[j] != QUIT; x++) {
            if (addIn[j] == addIns[x]) {
                foundIt[j] = x;
            }
        }
    }
    
    for(j=0; j<i-1; j++) {
        cout << addIn[j];
        if(foundIt[j] != -1) {
            cout << " $" << addInPrices[foundIt[j]] << endl;
            orderTotal = orderTotal + addInPrices[foundIt[j]];
        }
        else {
            cout << " - Sorry, we do not carry that." <<endl;
        }
    }

    cout << "$" << orderTotal <<endl;
    
    return 0;
}

Sample Outputs

Enter coffee add-ins followed by XXX to quit: Cream Cinnamon XXX
Cream $0.89
Cinnamon $0.25
$3.14
Enter coffee add-ins followed by XXX to quit: Cream Onion XXX
Cream $0.89
Onion - Sorry, we do not carry that.
$2.89

What I did was made addIn array of srings with NUM_ITEMS size instead of variable. Also, foundIt was made an integer array to keep track of indexes where the items are found in addIns array and -1 if not found.

To only access the items that user has entered in addIn, your QUIT has been made the termination condition in that array.

mr.loop
  • 818
  • 6
  • 20
  • This is it, thanks man I'm gonna translate this into a flowchart and see how it works really appreciate you taking the time to help me out! – Leo Sep 23 '21 at 04:41