Для списка меню, поскольку вы используете жестко запрограммированное меню, вы можете сделать что-то вроде следующих определений для создания меню.
Я изменил struct
, который вы предоставили, чтобы включить линейку продуктов Номер или PLU, который является стандартным идентификатором товаров в магазине. PLU назначаются каждому элементу в магазине и также используются для штрих-кодов.
typedef struct {
unsigned long ulPlu;
char szMnemonic[30];
long lPrice;
} MenuItem;
MenuItem myMenu[] = {
{11, "Cheese Cake", 90},
{12, "Chocolate Cake", 90},
{13, "Macha Cake", 90},
{21, "Red tea", 90},
{22, "Green tea", 90},
{0, "", 0} // PLU of 0 indicates the end of the menu list
};
Обычно поиск элемента выполняется путем поиска PLU в базе данных. В этом случае ваша база данных представляет собой просто небольшой резидентный массив пунктов меню. Ключом к данным является уникальный номер PLU, который назначается каждому элементу.
Самый простой способ сделать это - написать функцию, которая имеет в качестве аргументов номер PLU, который нужно искать вместе со списком меню. Функция использует al oop для перебора массива и сравнения номера PLU, введенного пользователем, с PLU каждого из пунктов меню. Если он находит совпадение, он возвращает этот элемент. Если этого не происходит, возвращается код ошибки.
Чтобы упростить лог c, я обычно использую дополнительный элемент массива MenuItem
со специальным кодом, который в противном случае не используется, чтобы указывают конец массива. Номер PLU никогда не должен быть нулем (0), поэтому я бы его использовал.
Альтернативой является передача количества элементов массива вместо зависимости от контрольного значения, такого как ноль. Самый простой способ сделать это с таким массивом, как приведенный выше, где все это определяется сгенерированным компилятором количеством элементов, - это использовать оператор sizeof()
, как в sizeof(myMenu)/sizeof(myMenu[0])
, который будет принимать общее количество байтов в массиве и затем разделите его на размер каждого элемента массива, чтобы вычислить количество элементов в массиве.
Если вы используете альтернативу, вы должны удалить контрольное значение или последнюю запись массива, {0, "", 0}
из определение массива, поскольку оно больше не требуется, поскольку вы используете количество элементов в массиве, а не контрольное значение, чтобы узнать, сколько l oop итераций нужно сделать до достижения конца массива.
#include <stdio.h>
typedef struct {
unsigned long ulPlu; // Product Line Unit number, unique to each item
char szMnemonic[30]; // mnemonic for the item
long lPrice; // price for the item with an assummed decimal point.
} MenuItem;
MenuItem myMenu[] = {
{11, "Cheese Cake", 90}, // menu item - PLU number, mnemonic, price
{12, "Chocolate Cake", 90},
{13, "Macha Cake", 90},
{21, "Red tea", 90},
{22, "Green tea", 90},
{0, "", 0} // special sentinal value to indicate end of the array.
};
typedef struct {
int errCode; // error code. 0 if no error.
const MenuItem * item; // pointer to the item found if errCode is zero.
} MenuItemRet;
// Lookup function that expects array to be terminated with an empty menu
// item that has a PLU number of zero.
MenuItemRet LookupPlu(unsigned long ulPlu, const MenuItem * myMenu)
{
MenuItemRet ret = { -1, NULL }; // default is the item not found case
for (size_t i = 0; myMenu[i].ulPlu != 0; i++) {
if (myMenu[i].ulPlu == ulPlu) {
MenuItemRet retFound = { 0, myMenu + i }; // found item. return pointer to item found.
return retFound;
}
}
return ret;
}
// Lookup function that requires the actual number of menu items in the array.
MenuItemRet LookupPlu2(unsigned long ulPlu, const MenuItem * myMenu, size_t nMenuCount)
{
MenuItemRet ret = { -1, NULL }; // default is the item not found case
for (size_t i = 0; i < nMenuCount; i++) {
if (myMenu[i].ulPlu == ulPlu) {
MenuItemRet retFound = { 0, myMenu + i }; // found item. return pointer to item found.
return retFound;
}
}
return ret;
}
int main()
{
MenuItem transactionData[100] = { {0, "", 0} }; // allocate a max transaction size.
unsigned short transactionIndex = 0;
long transactionTotal = 0;
unsigned long ulPlu = 0;
// as long as the user enters menu items we will add them to the transaction data
// until we reach the maximum number of items the transaction data area can hold.
while (transactionIndex < sizeof(transactionData)/sizeof(transactionData[0])) {
MenuItemRet menuItem;
printf ( "Enter PLU for item or 0 to exit\n");
scanf_s("%lu", &ulPlu);
if (ulPlu == 0) break;
#if USE_SENTINAL
// use the lookup function that requires a sentinal value.
if ((menuItem = LookupPlu(ulPlu, myMenu)).errCode >= 0) {
#else
// use the lookup function that requires number of menu items to be known.
// since we know a PLU value of zero is invalid, we do not bother trying to
// remove the last menu item from the array elements count as it will be ignored anyway.
if ((menuItem = LookupPlu2(ulPlu, myMenu, sizeof(myMenu)/sizeof(myMenu[0]))).errCode >= 0) {
#endif
// PLU lookup found this item so print out the item data then
// add the item to the transaction data.
printf("%s at %ld\n", menuItem.item->szMnemonic, menuItem.item->lPrice);
transactionData[transactionIndex++] = *menuItem.item;
}
else {
printf ( "PLU %lu does not exist\n", ulPlu);
}
}
// calculate the transaction total.
transactionTotal = 0;
for (unsigned short i = 0; i < transactionIndex; i++) {
transactionTotal += transactionData[i].lPrice;
}
printf("Transaction total = %ld", transactionTotal);
return 0;
}