본문 바로가기
프로그래밍/C++

C++ ] 자판기 (1)

by eteo 2022. 6. 16.

 

main.h

#ifndef __MAIN_H__
#define __MAIN_H__

typedef struct {
char name[20];
int price;
int stock;
} _DRINK;

namespace VendingMachine {
int DecideDrinkNum(void);
int SettingDrink(_DRINK* drink, const int& num);
bool Menu(_DRINK* drink, const int& num, int& money, int min);
int MoneyInput(void);
}

#endif

 

namespace를 사용하여 관련된 함수를 묶었다.

 

 

main.cpp

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include "main.h"

using namespace std;
using namespace VendingMachine;

int main(void) {

	int drink_num = 0;
	int MinPrice = 0;
	drink_num = DecideDrinkNum(); // 판매할 음료수 개수 결정

	_DRINK* Drink = new _DRINK[drink_num]; // 구조체배열 동적할당

	MinPrice = SettingDrink(Drink, drink_num); // 음료수 이름, 가격, 재고 설정 및 최저가 확인

	bool ReadyforSale = 1;

	while (1) {
		int money;
		if (ReadyforSale) {
			money = MoneyInput(); // 금액 투입
			ReadyforSale = 0;
		}
		ReadyforSale = Menu(Drink, drink_num, money, MinPrice); // money 는 참조자 써서 call by reference
	}
	delete[]Drink; // 동적할당 해제
	return 0;
}

 

처음에 DecideDrinkNum 함수를 통해 판매할 음료수 개수를 결정받고 해당 개수만큼 구조체배열을 동적할당 한다.

 

다음 SettingDrink함수를 통해 음료수의 이름/가격/재고를 설정하고 최저가를 확인하여 메인에 있는 MinPrice변수로 반환 받는다.

 

while문 내에서는 크게 MoneyInput이라는 금액 투입 함수와 Menu라는 판매 함수를 호출하고 Menu의 반환값을 bool 타입의 ReadyforSale 이라는 변수로 검사해서 반환이 1일 때 다시 금액투입 단계로 돌아가게끔 했다.

 

마지막으로 구조체배열 포인터의 동적할당을 해제한다.

 

 

 

main.cpp 의 함수 정의 부분

int VendingMachine::DecideDrinkNum(void) {
	int drink_num;
	cout << ">>>>>>> 음료수 자판기 설정을 시작합니다" << endl << endl;
	cout << "몇 개의 음료수를 판매하시겠습니까? ";
	cin >> drink_num;
	cout << endl << drink_num << " 개의 음료수를 판매하는 것으로 설정하셨습니다. ";
	system("pause");
	system("cls");
	return drink_num;
}

int VendingMachine::SettingDrink(_DRINK* drink, const int& num) {
	cout << ">>>>>>> 음료수의 종류와 가격 설정을 시작합니다" << endl << endl;
	for (int i = 0; i < num; i++) {
		cout << i + 1 << " 번째 음료수 명을 입력하세요 : ";
		cin >> drink[i].name;
		cout << i + 1 << " 번째 음료수 가격을 입력하세요 : ";
		cin >> drink[i].price;
		cout << i + 1 << " 번째 음료수 재고를 입력하세요 : ";
		cin >> drink[i].stock;
		cout << endl;
	}
	cout << ">>>>>>> 설정이 완료되었습니다. 자판기 판매를 시작합니다. ";
	system("pause");
	system("cls");
	int min = drink[0].price;
	for (int i = 0; i < num; i++) {
		min = (drink[i].price < min) ? drink[i].price : min;
	}
	return min;
}

int VendingMachine::MoneyInput(void) {
	int money;
	cout << "음료수 자판기==================================" << endl;
	cout << "돈을 투입해주세요: ";
	cin >> money;
	cout << endl;
	return money;
}

bool VendingMachine::Menu(_DRINK* drink, const int& num, int& money, int min)
{
	int select = 0;

	// 잔액이 음료수 중 최저가보다 작은 경우 바로 반환
	if (money < min) {
		cout << endl << "음료가 나옵니다." << endl;
		cout << "반환구에서 구입하신 음료와 거스름돈을 가져가세요." << endl;
		cout << "[ 거스름돈: " << money << "원 ]" << endl << endl;
		return 1;
	}
	cout << "[ 현재금액: " << money << "원 ]" << endl;
	for (int i = 0; i < num; i++) {
		printf("%d. %-10s %15d\n", i + 1, drink[i].name, drink[i].price);
	}
	cout << "----------------------------------------------" << endl << endl;
	printf("구입할 음료수를 선택해주세요: _ (음료를 꺼내려면 -1을 선택해주세요)\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
		cin >> select;

	// 사용자가 -1 선택한 경우 현재 잔액 반환
	if (select == -1) {
		cout << "반환구에서 구입하신 음료와 거스름돈을 가져가세요." << endl;
		cout << "[ 거스름돈: " << money << "원 ]" << endl << endl;
		return 1;
	}

	// 선택한 음료의 재고가 없거나 잔액이 부족한 경우가 아니라면 현재잔액에서 선택음료 가격 차감하고 재고 감소시킴
		if (money - drink[select - 1].price < 0) {
			cout << endl;
			cout << "잔액이 부족하여 해당제품은 구입할 수 없습니다. " << endl;
		}
		else if (drink[select - 1].stock <= 0) {
			cout << endl;
			cout << "재고가 부족하여 해당제품은 구입할 수 없습니다. " << endl;
		}
		else {
			money -= drink[select - 1].price;
			drink[select - 1].stock--;
		}
	return 0;
}