Кафе в программе c++


Я хочу построить кафе в C++. Я хочу, чтобы пользователь, чтобы ответить на каждый вопрос да или нет. Если они ответят да или нет, я хочу, чтобы отобразить их общей стоимости.

#include <iostream>
using namespace std;
int main()
{
    //Develop a billing statement for a store/restaurant 
    // Define variables 
    double donut, bagel, burrito, sandwhich, omelet, coffee, cappachino, smootie, water, spirit, total, tax;
    char answerType;
    bagel = 2.50;
    burrito = 3.50;
    donut = 1.00;
    sandwhich = 3.50;
    omelet = 1.25;
    coffee = 1.50;
    cappachino = 2.00;
    smootie = 3.25;
    water = 0.99;
    spirit = 1.00;
    total = 0.00;
    tax = 6.25;
    cout << "Welcome to Junelle's Cafe" << endl;
    // Introduction to my cafe

    //Customer knows the options before hand 
    //Customer enters yes (y) or no (n) 
    cout << "Enter a y (yes) or no (n) for every question asked." << endl;

//Ask user if they want a bagel 
    cout << "Would you like to buy a bagel for $2.50?:";
    cin >> answerType;

    if (answerType == 'y')

    {

        cout << "A bagel has been added to your order. Your total is " << total + bagel << endl;

    }

    else if (answerType == 'n')

    {
        cout << "Your total is " << total << endl;

    }
//item2
    cout << "Would you like to buy a donut for $1.00?:";
    cin >> answerType;

    if (answerType == 'y')

    {

        cout << "A donut has been added to your order. Your total is " << total + donut+bagel << endl;

    }


    else if (answerType == 'n')

    {
        cout << "Your total is " << total << endl;

    }
//item3 
    cout << "Would you like to buy a omelet for $1.25?:";
    cin >> answerType;

    if (answerType == 'y')

    {

        cout << "A omelet has been added to your order. Your total is " << total + donut + bagel+ omelet << endl;

    }

    else if (answerType == 'n')

    {
        cout << "Your total is " << total << endl;

    }
//item 4
    cout << "Would you like to buy a burrito for $2.50?:";
    cin >> answerType;

    if (answerType == 'y')

    {

        cout << "A burrito has been added to your order. Your total is " << total + donut + bagel
            + omelet + burrito << endl;

    }

    else if (answerType == 'n')

    {
        cout << "Your total is " << total << endl;

    }

//item 5 
    cout << "Would you like to buy a sandwhich for $2.50?:";
    cin >> answerType;

    if (answerType == 'y')

    {

        cout << "A sandwhich has been added to your order. Your total is " << total + donut + bagel
            + omelet+ burrito+sandwhich << endl;

    }

    else if (answerType == 'n')

    {
        cout << "Your total is " << total << endl;

    }
//item 6
    cout << "Would you like to buy a coffee for $1.50?:";
    cin >> answerType;

    if (answerType == 'y')

    {

        cout << "A coffee has been added to your order. Your total is " << total + donut + bagel 
            + omelet+ burrito + sandwhich + coffee<< endl;

    }

    else if (answerType == 'n')

    {
        cout << "Your total is " << total << endl;

    }

//item 7 
    cout << "Would you like to buy a cappachino for $2.00?:";
    cin >> answerType;

    if (answerType == 'y')

    {

        cout << "A cappachino has been added to your order. Your total is " << total + donut + bagel 
            + omelet + burrito + sandwhich + coffee+ cappachino << endl;

    }

    else if (answerType == 'n')

    {
        cout << "Your total is " << total << endl;

    }
//item 8
    cout << "Would you like to buy a water for $0.99?:";
    cin >> answerType;

    if (answerType == 'y')

    {

        cout << "A water has been added to your order. Your total is " << total + donut + bagel
            + omelet + burrito + sandwhich + coffee + cappachino + water << endl;

    }

    else if (answerType == 'n')

    {
        cout << "Your total is " << total << endl;

    }
//item 9 
    cout << "Would you like to buy a spirit for $1.00?:";
    cin >> answerType;

    if (answerType == 'y')

    {

        cout << "A spirit has been added to your order. Your total is " << total + donut + bagel
            + omelet + burrito + sandwhich + coffee + cappachino + water + spirit<< endl;

    }

    else if (answerType == 'n')

    {
        cout << "Your total is " << total << endl;

    }
//item 10 
    cout << "Would you like to buy a smootie for $1.25?:";
    cin >> answerType;

    if (answerType == 'y')

    {

        cout << "A smootie has been added to your order. Your total is " << total + donut + bagel 
            + omelet + burrito + sandwhich + coffee + cappachino + water + spirit + smootie << endl;

    }

    else if (answerType == 'n')

    {
        cout << "Your total is " << total << endl;

    }

    cout << "Thank you for visiting Junelle's Cafe" << endl;
    while (1);
    return 0;
}


9884
25
задан 5 февраля 2018 в 03:02 Источник Поделиться
Комментарии
4 ответа

Нет. Повторить. Себя.

Это важнейший принцип. Вы повторяете "ты хочешь ху" цикл снова и снова вручную. Это не только подвержено ошибкам, но также трудно поддерживать. Например, скажем, вы хотите спросить у клиента , сколько предметов они хотят. Тогда вам придется добавить или изменить обработку ввода для каждого отдельного элемента.

Может быть, вы хотите использовать

 15 bagels
200 coffee
1 water
1 donut

Это будет сделать довольно нудно делать, что в вашей текущей программе. Нам потребуется int bagelCount, coffeeCount, waterCount, coconoutCount…вы получаете шаблон.

Так вместо этого мы должны попытаться обработать все предметы таким же образом в один блок кода, если это возможно. Что приводит нас к следующей теме.

Повторное использование информации

В начале вашей программы, у вас есть bagel = 2.50. Однако, вы не используете эту информацию в своих интересах, когда вы спросите у клиентов, хотят ли они купить бублик:

cout << "Would you like to buy a bagel for $2.50?:";
^^^^^^

Это опять нарушение сухого. Если вы измените bagel цене, вам придется менять его в двух местах. Это может привести к ошибкам. Вместо повторного использования информации у вас уже есть под рукой:

std::cout << "Would you like to buy a bagel for $" << bagel << ": ";

Кстати, если переменная никогда не должны изменить его значение, объявить его const. Кроме того, попробуйте инициализировать свои переменные со значением, когда это возможно:

typedef double Price;

const Price bagelPrice = 2.50;
const Price coffeePrice = 1.50;

Но мы изменим это позже, так что не использовать это.

Не верь клиенту

Что происходит, если клиент входов 'а' вместо 'Y' или 'N'? Ну, ты это принимаешь и ничего не добавить.

Однако, если вы спросите клиента: "ты хочешь бублик?" и они отвечают "Ктулху!", вы, наверное, спросите их либо принять ваше предложение или отклонить. Небольшой

bool ask_yes_no() {
/* exercise */
}

функция может помочь вам.

Пространства имен

Если вы не знаете, что вы делаете не использовать using namespace std.

Абстракции

Теперь давайте посмотрим на один обменный пункт

//Ask user if they want a bagel 
cout << "Would you like to buy a bagel for $2.50?:";
cin >> answerType;

if (answerType == 'y')

{

cout << "A bagel has been added to your order. Your total is " << total + bagel << endl;

}

else if (answerType == 'n')

{
cout << "Your total is " << total << endl;

}

Все остальные предметы следуют той же структуре, так что давайте сосредоточимся на этом. Мы видим рисунок здесь:


  1. Мы говорим, что наименование товара и цена

  2. Мы спрашиваем, хотят ли они купить продукт

  3. Мы добавить товар в порядке и увеличить общее (этот шаг отсутствует)

  4. Мы рассказываем клиенту их новая общая

  5. Если у нас еще есть продуктов, мы выбираем следующего продукта и продолжить с 1.

  6. В противном случае мы говорим клиенту всего.

Поэтому давайте перепишем этот диалог:

std::cout << "Would you like to buy a " << item_name
<< " for $" << item_price << ": ";

if(asks_yes_no()) { // see exercise above
total += item_price;

std::cout << "A " << item_name<< " has been added to your order. ";
}

std::cout << "Your total is $" << total << ".";

Теперь нам нужен способ, чтобы получить item_name и item_price и пройти все пункты. Существует несколько способов:


  • мы можем использовать ассоциативный коллекции, например std::map<Name, Price>

  • мы можем пару имя и цена в один Item и использовать обычный коллекция std::vector<Item>

В другом обзоре используется последний, поэтому давайте посмотрим на прежний, std::map:

typedef std::string ItemName
typedef double Price;

const std::map<ItemName, Price> menu {
{"bagel", 2.50 },
{"coffee", 1.50 },
{"sugar", 0.02 },
{"full breakfast", 5.00}
};

Теперь мы можем перебрать все элементы в меню легко:

// You might not know this kind of loop yet.
// It's basically going through the menu.
// The current pair of item and price is item_and_price,
// the .first-Member is the item, and the .second-Member
// is the price.
//
// The following holds throughout the loop:
//
// menu[item_and_price.first] == item_and_price.second
for(const auto & item_and_price : menu) {
const auto & item_name = item_and_price.first;
const auto & item_price = item_and_price.second;

std::cout << "Would you like to buy a " << item_name
<< " for $" << item_price << ": ";

if(asks_yes_no()) { // see exercise above
total += item_price;

std::cout << "A " << item_name << " has been added to your order. ";
}

std::cout << "Your total is $" << total << ".";
}

Мы можем также сохранять треки заказа:

typedef unsigned int Amount;

std::map<ItemName, Amount> order;

/* ... */

total += item_price;

order[item_name] = 1;

Небольшое замечание по поводу значения с плавающей точкой

Арифметика с плавающей точкой не точны. Вместо doubleмы должны использовать точный тип и центов, а не с плавающей точкой типа и долларов, например

const Cents bagelPrice = 250;

Для небольшой игрушки программы, double нормально. Но если вы когда-нибудь брал деньги в ваш код, убедитесь, что ни клиент, вы, и правительство уделяют слишком много или не хватает денег.

Юзабилити

Последнее, но не менее, вы можете отобразить меню для пользователя и иметь их выбрать товар, который они хотят купить, например:

Добро пожаловать в наш магазин. Мы имеем следующие продукты под рукой:

1) Бублик ($2.50)
2) Кофе ($1.50)
3) Эспрессо ($1.50)
4) Завтрак ($5.20)
5) Проверка

Ваш выбор? [1-5]: 1

Количество бубликов: 20

Ваш заказ от 20 бубликов был зарегистрирован. Ваша новая сумма $50.00.

---- ---- ----

1) Бублик ($2.50)
2) Кофе ($1.50)
3) Эспрессо ($1.50)
4) Завтрак ($5.20)
5) Проверка

Вы заказали 20 бубликов. Ваш следующий выбор [1-5]: 5

Общая сумма $50.00. Спасибо за посещение и приходите еще!

Таким образом, они не придется пройти через все продукты, если они просто хотят купить 20 бубликов.

55
ответ дан 5 февраля 2018 в 06:02 Источник Поделиться

Это очень простой способ реализовать это, и это очень легко читать. Это здорово! Но это, возможно, произошло с вами, что есть более простой способ. Вот некоторые мысли о ее упрощении.

Использовать Классы

Обратите внимание, как у вас есть несколько элементов, которые все имеют те же свойства. Все они имеют название и цена. Поэтому есть смысл объединить их в класс. Простой класс может быть что-то вроде этого:

class InventoryItem {
public:
InventoryItem (const std::string& itemName, const double itemPrice);
~InventoryItem();

std::string getName() const;
double getPrice() const;

private:
std::string name;
double price;
};

Конструктор класса будет просто установить name поле перешло в название товара, и price поле сдали в пункт цена:

InventoryItem (const std::string& itemName, const double itemPrice) : 
name (itemName),
price(itemPrice)
{
}

В get функции просто возвращают значения:

std::string getName() const
{
return name;
}

Если у вас есть класс для этого, вы можете создавать объекты, делая что-то вроде этого:

InventoryItem newItem("burrito", 3.50);

Использовать Массивы

Поскольку у вас есть несколько элементов, и вы хотите сделать аналогичные операции на них, вы можете поместить их в array. В array имеет несколько элементов одного типа. Так что в данном случае мы хотим array из InventoryItemС. Мы можем создать один такой:

#include <array>

int main()
{
std::array<InventoryItem, 10> inventory {
InventoryItem("bagel", 2.50),
InventoryItem("burrito",3.50),
InventoryItem("donut", 1.00),
InventoryItem("sandwhich", 3.50),
InventoryItem("omelet", 1.25),
InventoryItem("coffee", 1.50),
InventoryItem("cappachino", 2.00),
InventoryItem("smootie", 3.25),
InventoryItem("water", 0.99),
InventoryItem("spirit", 1.00)
};

}

Когда у вас есть элементы в массив, и вы хотите сделать то же самое для каждого элемента, вы можете перебирать их в цикле. В array это типа "контейнер", потому что он содержит другие объекты. Все контейнеры поставляются в стандартной библиотеки шаблонов (это std:: префикс материалов) поставка объектов, называемых iteratorы, которые позволяют пройти через каждый элемент в контейнере. Вы просто позвоните container.begin() чтобы получить итератор, указывающий на первый элемент в контейнере, затем увеличивать его, чтобы получить следующий. Вы можете сохранить увеличивая его, пока он не равен container.end()и тогда вы знаете, что у вас нет больше в процесс. Так давайте попробуем, что с выше array материально-производственных запасов:

for (std::array<InventoryItem, 10>::iterator nextItem = inventory.begin();
nextItem != inventory.end();
nextItem++)
{
std::cout << "Would you like to buy a " << nextItem->getName();
std::cout << " for " << nextItem->getPrice() << "?\n";

std::cin >> answerType;

if (answerType == 'y')
{
std::cout << "A " << nextItem->getName();
std::cout << " has been added to your order. Your total is ";
std::cout << total << "\n";
}
else
{
std::cout << "Your total is " << total << "\n";
}
}

Теперь заметил кое-что странное О total? Не обновляется должным образом. Я не добавить стоимость товара в целом. Причина не в том, что я хочу посмотреть, как вы это сделали в вашей версии. В свой первый if заявление, если пользователь выбирает "г", распечатать total + bagel. Но заметьте, что вы на самом деле не обновление totalвы только ее напечатали. Вам нужно назначить новую цену total. Так что вам нужно сделать что-то вроде этого:

total = total + bagel;

Или в моем варианте с array и петли, это будет просто:

total = total + nextItem->getPrice();

Также обратите внимание, что в вашей версии, для второй if заявление, когда пользователь выбирает "г" печати цена бублик и пончик. Но что делать, если пользователь выбрал "н" за бублик и "y" за донат? Вы будете печатать неправильную цену!

Так что если вам отслеживать общее, как вы идете, и обновлять его после каждого "г" выбора, то он всегда должен иметь правильное значение, и вам не придется вручную добавлять во все другие варианты.

И вы можете закончить его так же, как вы конец вашей версии:

cout << "Thank you for visiting Junelle's Cafe" << endl;
while (1);
return 0;

Спасибо, что позволили нам падение!

22
ответ дан 5 февраля 2018 в 04:02 Источник Поделиться

В дополнение к выше ответы

Никогда не используйте числа с плавающей точкой в финансовых расчетах

Это не хорошо, как с плавающей точкой не являются точными дополнениями и округление распространяется ошибки в интуитивно понятным способом. Очень вероятно, что один теряет или получает 1 цент при выполнении более сложных вычислений.

Это может работать на ваш простой пример, но обратите внимание, что бухгалтерские системы обычно работают с фиксированной точкой представление.

Поскольку C++ не поддерживает фиксированный момент самое простое решение заключается в использовании целых чисел и в магазине Все цены в центах.

18
ответ дан 5 февраля 2018 в 09:02 Источник Поделиться

Там уже есть несколько отличных советов, но я заметил, что некоторые из он использовал STL, который вы, вероятно, не будет учиться на некоторое время. Вы можете значительно упростить свою программу, с помощью класса, чтобы включить функциональность в кафе.

что-то вроде этого:

struct Product
{
static float total;
static constexpr float tax = 6.25;
char desc[16];
float price;
bool pitchItem();
}productList[10] =
{
"bagel",2.50,
"burrito",3.50,
"donut", 1.00,
"sandwich", 3.50,
"omlet", 1.25,
"coffee", 1.50,
"cappachino", 2.00,
"smoothie", 3.25,
"water", .99,
"spirit",1.00
};

Эта структура продукт содержит всю информацию, вам нужно. Статические члены являются членами класса, а не объекта, поэтому они могут быть использованы для хранения глобальных или обобщенную информацию. Методы не нужны параметры, в этом случае, потому что они предполагают, что вы имеете в виду desc и значения цен в рамках.

В этом примере все размеры являются статическими. Это не самый эффективный способ программу в целях экономии пространства, но ничего больше было бы перебор и я намеренно держусь подальше от STL и динамической памяти, потому что я думаю, ты не научился еще.

В pitchItem() метод удаляет избыточные набора текста, делать что-то вроде этого:

bool Product::pitchItem()
{
bool goodAnswer = true;
char answer;
std::cout << "Would you like to buy a " << desc << "?: ";
std::cin >> answer;
if(answer == 'y' || answer == 'Y')
{
total += price;
std::cout << "A "<< desc << " has been added to your order. Your total is $"<< std::fixed << std::setprecision(2) <<total << "\n";
}
else if(answer == 'n' || answer == 'N')
{
std::cout << "Your total is $" << total << "\n";
}
else
{
std::cout << "Sorry, I must have misunderstood you.\n";
goodAnswer = false;
}
return goodAnswer;
}

Делать что-то вроде этого позволяет перебрать все варианты с помощью цикла for. Статус вопрос возвращается, так что вы можете сделать что-то подобное, чтобы убедиться, что входной сигнал является действительным:

    if(!productList[i].pitchItem())
{
i--;
}

Надеюсь, что помогает.

1
ответ дан 8 февраля 2018 в 07:02 Источник Поделиться