저번에 작업하던 영화 예매 프로그램 중간과정의 마지막 단계인 영화 티켓 예매 파트를 완성했고, 코드가 난잡하게 널려있던 부분을 정리했다.


불필요한 필드 및 메소드는 모두 주석 처리를 했다.


1. 상영관 관리 프로그램 O

2. 영화 상영일정 관리 프로그램 O

3. 영화 티켓 예매 프로그램 O


이로써 완성~


예외처리 할게 널려있지만 일단은 정상적으로 입력시 정확히 작동하는 것을 확인했다.


아래는 각 클래스의 소스코드.


ps. 영화 예매 관리 프로그램에서 예매시 유저를 구분할 수 있는 고유 넘버는 10000으로 시작해서 유저가 추가 될 때마다 +1 씩 고유 넘버가 증가한다.





블로그 이미지

irostub

iro의 잡화상점

,


적당한 과제로 영화 예매 프로그램을 작성하게 되었다.


과정은 1~3단계로 나뉘어져 있고 모든 단계가 개체에 대한 적절한 이해가 필요한 과제였다. 현재는 1~2단계까지 코드를 완성했고, 마지막 제출까지 3단계를 끝마쳐야한다.


영화 예매 프로그램은 파트별로 크게 3가지로 나뉘어져있다.


1. 상영관 관리 프로그램

2. 영화 상영일정 관리 프로그램

3. 영화 티켓 예매 프로그램


각각 기능별로

0- 메인은 MovieReservation 클래스

1- 상영관 관리 프로그램은 Sceen, ScreenManager 클래스

2- 영화 상영일정 관리 프로그램은 Movie, MovieTimetable, TimetableManager 클래스

3- 영화 티켓 예매 프로그램은 Seat, Ticket, TicketManager클래스


를 필요로 한다. 현재는 1, 2 만 구현했으며 내부 메소드 중에 3과 연관 되는 메소드는 틀만 작성했다.


객체를 생성해서 배열을 뒤지는 과정에서 계산을 잘못해서 NullPointException이 엄~청 많이 발생했으나 환기 한번하고 천천히 다시 건드려보니 모두 해결되었다.


무식하게 복사 붙여넣기해서 길어졌던 코드도 중복을 제거하고 최대한 간결하게 정돈했다.


2파트 까지는 만족! 3파트까지 모두 완성되면 최종 편집본으로 다시 한번 글을 작성할 생각이다.


아래는 각 클래스별 코드이다. 코드가 적잖이 기므로 접기.




1. 상영관 관리 프로그램에 대한 Screen, ScreenManager 클래스







2. 영화 상영일정 관리 프로그램 Movie, MovieTimetable, TimetableManager 클래스



블로그 이미지

irostub

iro의 잡화상점

,
학교에서 내준 실습과제다 예제와 일치하도록 코딩은 한 것 같은데,

가만보니 테이블 삭제했을 때 뭔가 이상할 것 같다.  

실제로 2번 테이블 손님 그냥 나갔다고 삭제하면, 3번 테이블 손님이 2번 테이블로 오는건 아니잖아?
 
아무래도 예제가 잘못된거같다. 

차라리 포인터 배열을 당기는 형식이아니라. 

cnt 변수도 필요도록 삭제한 뒤 NULL로 포인터 배열 초기화하고, 객체는 delete 하는 방식이 더 옳아보인다.  

추가 할 땐 대신 NULL이 아니면 그 자리에 추가가 안되도록 하고 삭제를 하라고 안내해 주는 방법이 훨씬 현실적일 것. 

그래도 재미는 있었다. 포인터가지고 짱구 굴리는게 다중포인터 이해엔 확실히 도움이된다.
#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;

#define MIN_TABLE 0
#define MAX_TABLE 10
struct Menu {
	int food_num = 0;
	string food_name = "";
	int price = 0;
};

struct Order {
	Menu *food = NULL;
	int *food_quantity = 0;
	int table_num = 0;
	int order_count = 0;
	int total_price = 0;
	bool isChecked = false;
};

//start function 
void print_order();
void new_order(Menu*, Order**, int&);
void find_order(Order**, int);
void check_order(Order**, int);
void del_order(Order**, int&);
//end function

int main()
{
	Menu menu[6] = { { 1,"그린샐러드",18000 },{ 2,"치킨샐러드",19000 },{ 3,"찹스테이크",32000 },
	{ 4,"티본스테이크",30000 },{ 5,"치즈파스타",17000 },{ 6,"치즈피자",15000 } };
	Order *order[10] = { NULL };

	int selectMenu = 0;
	int cnt = 0;

	while (selectMenu != -1)
	{
		print_order();
		cin >> selectMenu;

		switch (selectMenu)
		{
		case 1:
			//if (order[cnt] == NULL)
			//{
			new_order(menu, order, cnt);
			//}
			break;
		case 2: find_order(order, cnt); break;
		case 3: check_order(order, cnt); break;
		case 4: del_order(order, cnt); break;
		case 0:
			delete(order);
			selectMenu = -1;
		default: cout << "비정상적인 입력입니다." << endl; break;
		}
	}
}

void new_order(Menu* m, Order **ptr_array_order, int& pos)
{
	Order *o = new Order;
	bool search = false;
	cout << "*주문받을 테이블번호(1-10) 선택 : "; cin >> o->table_num;

	//start input error check
	if (o->table_num <= MIN_TABLE || o->table_num > MAX_TABLE)
	{
		cout << "테이블 번호 입력오류입니다. 처음화면으로 돌아갑니다." << endl;
		delete(o); return;
	}
	//end input error check

	cout << "* 주문할 음식 수 입력 : "; cin >> o->order_count;

	o->food = new Menu[o->order_count];
	o->food_quantity = new int[o->order_count];

	for (int i = 0; i < o->order_count; i++)
	{
		cout << "주문 " << (i + 1) << " 을 입력하세요 : ";
		string name; cin >> name;

		//start copy food object
		for (int j = 0; j < 6; j++)
		{
			if (name == m[j].food_name)
			{
				o->food[i] = m[j];
				search = true;
				break;
			}
		}
		if (search == false)
		{
			cout << "해당하는 주문은 없습니다. 처음화면으로 돌아갑니다." << endl;
			break;
		}
		//end copy

		//start input to food_quantitiy 
		cout << "수량을 입력하세요" << (i + 1) << " : ";
		cin >> o->food_quantity[i];
		//end input

		o->total_price += o->food[i].price * o->food_quantity[i];//acc in total_price
	}
	if (search == false)
	{
		delete(o);
		return;
	}
	*(ptr_array_order + pos++) = o; //reg order

	cout << "주문이 등록됬습니다." << endl << endl;
	search = false;
}

void find_order(Order **ptr_array_order, int pos)
{
	int table_num = 0;

	cout << "*검색할 테이블번호(1-10) 선택 : "; cin >> table_num;

	if (table_num <= MIN_TABLE || table_num > MAX_TABLE)
	{
		cout << "테이블 번호 입력오류입니다. 처음화면으로 돌아갑니다." << endl;
		return;
	}

	for (int i = 0; i < pos; i++)
	{
		if (table_num == ptr_array_order[i]->table_num)
		{
			//start print 
			for (int j = 0; j < ptr_array_order[i]->order_count; j++)
			{
				cout << ptr_array_order[i]->food[j].food_name << " : " <<
					ptr_array_order[i]->food[j].price << " * " <<
					ptr_array_order[i]->food_quantity[j] << " = " <<
					ptr_array_order[i]->food[j].price * ptr_array_order[i]->food_quantity[j] << endl;
			}//end print

			cout << "주문금액 = " << ptr_array_order[i]->total_price << endl;
			int vat = ptr_array_order[i]->total_price * 0.1;
			cout << "부가세 = " << vat << endl;
			cout << "결제예정금액 = " << ptr_array_order[i]->total_price + vat << endl;
		}
	}
}

void check_order(Order** ptr_array_order, int pos)
{
	int table_num = 0;
	int received_money = 0;

	cout << "*결제할 테이블번호(1-10) 선택 : "; cin >> table_num;

	if (table_num <= MIN_TABLE || table_num > MAX_TABLE)
	{
		cout << "테이블 번호 입력오류입니다. 처음화면으로 돌아갑니다." << endl;
		return;
	}
	cout << "받은 금액 입력 : "; cin >> received_money;

	for (int i = 0; i < pos; i++)
	{
		if (table_num == ptr_array_order[i]->table_num)
		{
			if (received_money >= ptr_array_order[i]->total_price + ptr_array_order[i]->total_price*0.1)
			{
				cout << "반환 금액 = " << received_money - ((ptr_array_order[i]->total_price) + (ptr_array_order[i]->total_price*0.1)) << endl;
				ptr_array_order[i]->isChecked = true;
				cout << "결제가 완료되었습니다." << endl;
				break;
			}
			else
			{
				cout << "결제 금액이 부족합니다. 다시 결제해주세요." << endl;
				break; return;
			}
		}
	}
}

void del_order(Order** ptr_array_order, int& pos)
{
	int table_num = 0;
	cout << "*삭제할 테이블번호(1-10) 선택 : "; cin >> table_num;

	if (table_num <= MIN_TABLE || table_num > MAX_TABLE)
	{
		cout << "테이블 번호 입력오류입니다. 처음화면으로 돌아갑니다." << endl;
		return;
	}

	for (int i = 0; i < pos; i++)
	{
		if (ptr_array_order[i]->table_num == table_num)
		{
			if (ptr_array_order[i]->isChecked == false)
			{
				//ptr_array_order[i] = NULL;

				delete(ptr_array_order[i]);
				//start swap pointer
				for (int j = i; j < pos - 1; j++)
				{
					cout << "here";
					ptr_array_order[j] = ptr_array_order[j + 1];
					ptr_array_order[j]->table_num -= 1;
				}
				//end swap pointer
				pos -= 1;
				cout << "삭제를 완료하였습니다." << endl;
				break;
			}
			else
			{
				cout << "결제완료한 주문은 삭제할 수 없습니다." << endl;
				break;
			}
		}
	}
}

void print_order()
{
	cout << "**** 해피 패밀리 레스토랑 ****" << endl;
	cout << "\t1.주문입력" << endl;
	cout << "\t2.주문검색" << endl;
	cout << "\t3.주문결제" << endl;
	cout << "\t4.주문삭제" << endl;
	cout << "\t0.종료" << endl;
	cout << "******************************" << endl;
}


블로그 이미지

irostub

iro의 잡화상점

,

몇가지 배웠던거 짬뽕해서 날림으로 작성해봤다.

뭐 무슨 컵에 뭐 넣고 무슨 컵에 뭐 넣고 출력하는 것인데, 연산까지 넣기엔 이미 졸려버릴 시간이라...나~중에 주말에나 볼만하도록 할 수 있겠다.


#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;

int main()
{
	bool mainSwitch = false;

	int cup = 0;
	float water = 0.0f;

	char cup1_Name[50] = "";
	string inputS;
	string cup2_Name = "";

	cout << "컵을 실행하시겠습니까? (yes or no)";
	cin >> inputS;

	while (true)
	{
		if (inputS == "no")
		{
			cout << "프로그램을 종료합니다." << endl;
			break;
		}
		else if (inputS == "yes")
		{
			mainSwitch = true;

			while (mainSwitch)
			{
				cout << "첫번째 컵에 무엇을 얼마나 따릅니까? (스페이스바로 입력구분)" << endl;
				cin >> cup1_Name >> water;

				cout << "두번째 컵에 무엇을 얼마나 따릅니까? (스페이스바로 입력구분)" << endl;
				cin >> cup2_Name >> cup;

				cout << "각 컵에 들어간 액체의 종류와 g(gram)수" << endl;
				cout << cup1_Name << " : " << water << "g" << endl;
				cout << cup2_Name << " : " << cup << "g" << endl;

				string outi = "";
				cout << "프로그램을 종료하려면 yes를 계속하시려면 no를 입력해주세요. ";
				cin >> outi;
				if (outi == "yes")
				{
					mainSwitch = false;
					inputS = "no";
				}
			}
		}
		else
		{
			cout << "잘못 입력하셨습니다. yes or no 로 대답해주십시오." << endl;
		}
	}
}


블로그 이미지

irostub

iro의 잡화상점

,

자료형 수업과 같이 나온 예제. 시프트 연산이 나오지 않는 이상 기본적인 5칙연산자에선 어려운 부분이 별로 없기에 간단했던 코딩.


예제2) 물건을 사고 남은 잔돈을 500원, 100원, 10원 단위로 분류하여라


#include "stdafx.h"
#include <iostream>
using namespace  std;

int main()
{
	int getCoin = 0;
	int sellCoin = 0;
	int haveCoin = 0;

	int count = 0;

	cout << "현재 소지금을 입력하세요 : ";
	cin >> getCoin;
	cout << "구입 금액을 입력하세요 : ";
	cin >> sellCoin;

	haveCoin = getCoin - sellCoin;

	count = haveCoin / 500;
	haveCoin %= 500;

	cout << "500원 : " << count << " 개"<<endl;
	count = 0;
	
	count = haveCoin / 100;
	haveCoin %= 100;

	cout << "100원 : " << count << " 개" << endl;
	count = 0;
	
	count = haveCoin / 10;
	haveCoin %= 10;

	cout << "10원 : " << count << " 개" << endl;

	return 0;

}


이것 또한 약간의 차이가 있었는데, 동전의 단위마다 카운터를 올릴 변수를 모두 선언한 방식과 그냥 카운터 변수 하나를 계속 0으로 초기화 해가며 출력한 방식 정도가 달랐다. 큰 문제가 없으므로 ~~

블로그 이미지

irostub

iro의 잡화상점

,

오늘 강의에서 실습한 예제. 다양한 자료형을 입력받고 수순대로 출력하는 간단한 코딩이다.


예제1) 자료형에 맞게 입력을 받고 출력하시오.


#include "stdafx.h"
#include <iostream>
#include <string>

using namespace std;

int main()
{
	char name[100] = "";
	short cc = 0;
	float weight = 0;
	//char engineT[2] = "";
	string engine = "";

	cout << "차종을 입력하세요 :";
	cin >> name;
	cout << "배기량을 입력하세요 :";
	cin >> cc;
	cout << "중량을 입력하세요 :";
	cin >> weight;
	cout << "연료 타입을 입력하세요 (a. 휘발류, b. 경유) :";
	cin >> engine;

	if (engine == "a")
	{
		cout << name << "/" << cc << "/" << weight << "/" << "휘발류"<<endl;
	}
	else
	{
		cout << name << "/" << cc << " CC /" << weight << " Ton /" << "경유" << endl;
	}

	return 0;
}


교수님이 작성한 답안과 약간의 차이가 있었지만, string과 C-string의 차이이므로 큰 문제는 없다.

블로그 이미지

irostub

iro의 잡화상점

,

예제 3)km를 mile로 환산


다른 환산 로직과 별다를 것은 없다. 반복학습의 일환.


확실히 작성하면서 느끼는데, 개인적으로 묵시적 형 변환보단 명시적 형 변환이 더 깔끔하다고 느껴진다.

#include "stdafx.h"
#include <iostream>
using namespace std;

int main()
{
	int km = 0;
	float mile = 0;

	cout << "km값을 입력하세요 : ";
	cin >> km;

	mile = (float)km * 0.62f;

	cout << km << "km는 " << mile << "mile입니다.";
}



블로그 이미지

irostub

iro의 잡화상점

,

예제 2) 시,분,초를 입력받아 초로 환산하여라.


배운 내용대로 구성하자면 ' ' - 공백으로 구분하여 각각 시분초 변수에 입력받고 연산을 결과값에 누적시켜주는 것으로 완성.


#include "stdafx.h"
#include <iostream>
using namespace std;

int main()
{
	//TODO : 시 분 초를 입력받아 초로 변환
	int hour, minute, second, result;

	cout << "시, 분, 초 를 ' '으로 구분하여 입력하세요 : ";
	cin >> hour >> minute >> second;

	result = hour * 3600;
	result += minute * 60;
	result += second;

	cout <<"시간을 초로 환산한 값은 " << result <<" 입니다.";
}


조금 더 나아가서 C-String을 사용하면 공백문자로 아리쏭하게 입력받는 것이 아닌

 x : x : x 로 입력 받는 것이 가능할 것 같다.


#include "stdafx.h"
#include <iostream>
using namespace std;

int main()
{
	char inputTime[50];
	int result = 0;
	char temp[10];

	cout << "시:분:초 를 입력하세요 : ";

	for (int i = 0; i < 2; i++)
	{
		cin.getline(inputTime, 50, ':');
		strcpy_s(temp, inputTime);

		if (i == 0)
		{
			result += atoi(temp) * 3600;
		}
		else if (i == 1)
		{
			result += atoi(temp) * 60;
		}
	}
	result += atoi(inputTime);

	cout << "시간을 초로 환산한 값은 " << result << " 입니다.";
}


이렇게 하면 조금 더 자연스럽게 시:분:초 를 입력할 수 있다. 큰 차이는 없지만 스페이스바로 띄워서 구분하는 것보다 ':'를 기준으로 구분하는 것이..조금의 차이점?



블로그 이미지

irostub

iro의 잡화상점

,