C++

C++ 배열

Machine_웅 2022. 11. 1. 13:08
728x90
반응형
// 선행처리 지시문
#include <iostream>
#include <algorithm>
#include <string>
#include <iomanip>

//헤더 추가 -> 클래스
#include "Date.h"
#include "Person.h"
#include "Wlink.h"
#include "CLink.h"

// -< 배열 CRUD >-------------------------------------------------------------------------
int ListPersoinMain();
bool addPerson( Person& );
bool addArray( Person* arr, Person  item );
void deleteData( Person* tmp );
void editData( int choice, Person* tmp );
void editMenu( Person* target );
bool isCanInsertData( Person* arr );
void menu( int a, Person* );
void orderArr( Person* arr, int index );
Person* personChoice( Person* arr );
int selectMenu();
string setPersonName();
Date* setPersonBirth();
double setPersonHeight();
double setPersonWeight();
void showList( Person* arr );
void showMenu();
const int arrSize = 10;


int Main()
{

	Person pArr[arrSize]; //  초기화가 되지 않고 쓰레기값을 가리킨다.
 // 배열의 길이 구하기 
 // int len = sizeof( pArr ) / sizeof( pArr[0] ); 

	int choiceResult = 0;
	while ( 1 ) {
		int menuMode = 0;
		showMenu();
		choiceResult = selectMenu();
		if ( choiceResult == -1 ) {
			break;
		}
		else {
			// 배열의 시작 주소를 보내기때문에, 파라미터로 받는 함수에서는 배열의 길이를 알수 없다.
			menu( choiceResult, pArr );
		}
	}
	return 0;
};
void showMenu() {
	cout << "=====<<메뉴 선택>>=====" << endl;
	cout << "1.사람 리스트 보기 " << endl;
	cout << "2.사람 추가" << endl;
	cout << "3.사람 수정" << endl;
	cout << "4.사람 삭제" << endl;
	cout << "-1. 프로그램 종료" << endl;
	cout << "======================= " << endl << endl;
}
void menu( int a, Person* arr ) {
	/*
	 그런데 다음과 같이 함수의 인자로 배열을 넘겨받아서 위와 같이 계산하면 구할 수 없다.
	 그 이유는 인자로 arr을 받을 때 배열이 아닌 포인터로 받기 때문이다.
	 즉 배열의 이름(주소)을 받는다. 그래서 분자가 배열의 크기가 아닌 포인터의 크기가 된다.
	 */
	switch ( a )
	{
		case 1: {
				showList( arr );
				break;
			}
		case 2: {
				// 임시 값을 만들어 주소값을 전달.

				if ( isCanInsertData( arr ) ) {
					Person tmp;
					Person* tmpR = new Person; // 메모리를 할당할 녀석을 임시로 만들어준다. 
					bool result = addPerson( tmp );
					if ( result ) {
						cout << "입력 완료 " << endl;
						tmpR = &tmp;  // tmpR->viewData(); // tmp.viewData();
						addArray( arr, *tmpR );
					}
					else {
						// 실패라면 메모리 해제
						cout << "입력 취소 " << endl;
						delete tmpR;
					}
				}
				else {
					cout << "데이터가 가득 찼습니다. 더이상 추가가 불가능합니다.  " << endl;
				}
				break;
			}
		case 3: {
				Person* tmp;
				tmp = personChoice( arr ); // 1: 수정 2 :삭제 

				if ( tmp != nullptr ) {
					editMenu( tmp );
				}
				else {
					cout << "없음";
				}
				break;
			}
		case 4: {
				deleteData( arr );


				break;
			}
		default:
			break;
	}
}
int selectMenu() {
	int menuChoice;
	cout << "입력  ( 종료는 -1 ) => ";
	cin >> menuChoice;
	return menuChoice;
}

//  사람 선택 
Person* personChoice( Person* arr ) {
	cout << "수정할 리스트 번호를 입력해주세요. : " << endl;

	Person* tmp;

	for ( int i = 0; i < 10; i++ ) {
		if ( !arr[i].getName().empty() ) {
			cout << i + 1 << " 번 Data => ";
			arr[i].viewData();
			cout << endl;
		}
	}
	int choice = 0;
	while ( true )
	{
		cout << "선택 (  종료는 -1 ) => ";
		cin >> choice;
		if ( choice == -1 ) {
			tmp = nullptr;
			break;
		}
		else {  // Todo 배열 유효성 검사를 하긴 해야함..
			tmp = &arr[choice - 1];
			if ( tmp->getName().empty() ) {
				cout << "수정할 데이터가 올바르지 않습니다. =>  " << endl;
			}
			else {
				cout << "수정할 데이터 입니다. =>  " << endl;
				tmp->viewData();
				break;
			}
		}
	}

	return tmp;
}

// CRUD
bool addArray( Person* arr, Person item ) {
	cout << "리스트(배열)에 추가합니다.... " << endl;
	for ( int i = 0; i < 10; i++ ) {
		std::string tmpName = arr[i].getName();
		if ( tmpName.empty() ) {
			arr[i].setPerson( item );
			cout << "추가 완료" << endl;
			break;
		}
		else {
			continue;
		}
	}
	return 0;
}

string setPersonName() {
	cout << "  이름 입력 :  ";
	string name;
	std::cin >> name;

		// 문자열 비교
	if ( name.compare( "-1" ) == 0 ) {
		return "-1";
	}
	else {
		return name;
	}
}
Date* setPersonBirth() {
	Date tmpD;
	cout << "  생년월일 (년도 입력) :  ";
	int year;
	std::cin >> year;
	if ( year == -1 ) {
		return nullptr;
	}
	else {
		tmpD.setYear( year );
	}
	cout << "  생년월일 (월 입력) :  ";
	int month;
	std::cin >> month;
	if ( month == -1 ) {
		return nullptr;
	}
	else {
		tmpD.setMonth( month );
	}
	cout << "  생년월일 (일 입력) :  ";
	int day;
	std::cin >> day;
	if ( day == -1 ) {
		return nullptr;
	}
	else {
		tmpD.setDay( day );
		// tmpP.setBirth( tmpD );
	}
	tmpD.showDate();
	return &tmpD;
}
double setPersonHeight() {
	cout << "  키 입력 :  ";
	double height;
	std::cin >> height;
	if ( height == -1 ) {
		return -1;
	}
	else {
		return height;
	}
}
double setPersonWeight() {
	cout << "  몸무게 입력 :  ";
	double weight;
	std::cin >> weight;
	if ( weight == -1 ) {
		return -1;
	}
	else {
		return weight;
	}
}

bool isCanInsertData( Person* arr ) {
	bool isSpace = false;
	for ( int i = 0; i < arrSize; i++ ) {
		if ( arr[i].getName().empty() ) {
			isSpace = true;
			break;
		}
	}
	return isSpace;
}
bool addPerson( Person& tmpP ) {
	Date* tmpD = new Date;
	cout << "=====<<사람 추가>>=====" << endl;
	cout << "  - 1 :    취소  " << endl;

	string name = setPersonName();
	if ( name == "-1" ) {

	}
	tmpP.setName( name );
	tmpD = setPersonBirth();
	if ( tmpD == nullptr ) {
		return false;
	}
	else {
		tmpP.setBirth( *tmpD );
	}

	double height = setPersonHeight();
	if ( height == -1 ) {
		return false;
	}
	else {
		tmpP.setHeight( height );
	}

	double weight = setPersonWeight();
	if ( weight == -1 ) {
		return false;
	}
	else {
		tmpP.setWeight( weight );
	}
	return true;
}
void showList( Person* arr ) {
	for ( int i = 0; i < 10; i++ ) {
		// cout << "arr[i].getName() : " << arr[i].getName() << endl;
		if ( !arr[i].getName().empty() ) {
			cout << i + 1 << " 번 Data => ";
			arr[i].viewData();
			cout << endl;
		}
	}
}
void editMenu( Person* target ) {
	int choice = -2;

	// 값을 복사하기위해서 새로 주소를 할당하고, 그 주소에 값을 넣음.
	Person* tmp = new Person;
	*tmp = *target;

	while ( true )
	{
		cout << "===현재 데이터 =============>  " << endl;
		target->viewData();
		cout << "==수정할 목록을 선택해주세요. ==>  " << endl;
		cout << "1. 이름 수정    " << endl;
		cout << "2. 생년월일 수정  " << endl;
		cout << "3. 키 수정   " << endl;
		cout << "4. 몸무게 수정   " << endl;
		cout << "취소는 -1   " << endl;
		cout << "저장은  0   " << endl;
		cout << "입력 =>   " << endl;
		cin >> choice;

		if ( choice == -1 ) {
			delete tmp;
			break;
		}
		else if ( choice == 0 ) {
			*target = *tmp;
			cout << "===저장 데이터 =============>  " << endl;
			target->viewData();
			break;
		}
		else {
			editData( choice, tmp );
			cout << "===수정 데이터 =============>  " << endl << endl;
			tmp->viewData();
		}
	}
}
void editData( int choice, Person* tmp ) {

	switch ( choice )
	{
		case 1: {
				string name = "";
				cout << "===== 이름 수정============= " << endl;
				cout << "===== 이전 데이터:" << tmp->getName() << " ===== " << endl;
				name = setPersonName();
				if ( name == "-1" ) {
					return;
				}
				else {
					tmp->setName( name );
				}
				break;
			}
		case 2: {
				Date* date = new Date();
				cout << "===== 생년월일 수정============= " << endl;
				cout << "===== 이전 데이터:" << tmp->getBirth().showDate() << " ===== " << endl;
				date = setPersonBirth();
				if ( date == nullptr ) {
					delete date;
					return;
				}
				else {
					tmp->setBirth( *date );
				}
				break;
			}
		case 3: {
				double height = 0;
				cout << "===== 키 수정============= " << endl;
				cout << "===== 이전 데이터:" << tmp->getHeight() << " ===== " << endl;
				height = setPersonHeight();
				if ( height == -1 ) {
					return;
				}
				else {
					tmp->setHeight( height );
				}
				break;
			}
		case 4: {
				double weight = 0;
				cout << "===== 몸무게 수정============= " << endl;
				cout << "===== 이전 데이터:" << tmp->getWeight() << " ===== " << endl;
				weight = setPersonWeight();
				if ( weight == -1 ) {
					return;
				}
				else {
					tmp->setWeight( weight );
				}
				break;
			}

		default:
			break;
	}
}
void deleteData( Person* arr ) {
	int choice = -1;

	while ( true )
	{
		cout << "=====<<데이터 삭제>>=====" << endl;
		cout << "삭제할 데이터의 번호를 입력하세요." << endl;
		showList( arr );
		cout << "  - 1 :    취소  " << endl;
		cin >> choice;

		if ( choice == -1 ) {
			break;
		}
		else {
			int index = choice - 1;
			string name = arr[index].getName();
			if ( name.empty() ) {
				cout << "잘못된 대상입니다. " << endl;
			}
			else {
				orderArr( arr, index );
			}

		}
	}
}
void orderArr( Person* arr, int index ) {
	int checkIndex = index + 1;
	int count = 0; // 복사할 배열의 사이즈
	// 끝 배열인지 아닌지 확인

	string tmp = arr[index].getName();
	if ( tmp.empty() ) {
		Person clearObj = Person();
		arr[index] = clearObj;
	}
	else {

		try
		{
			while ( true )
			{
				string tmp = arr[checkIndex].getName();
				if ( tmp.empty() ) {
					break;
				}
				else {
					checkIndex++;
					count++;
				}
			}
		}
		catch ( const std::exception& )
		{
			count = 0;
		}


		for ( int i = index; i <= count + index; i++ ) {
			cout << "index  :  " << i << endl;
			if ( i == count + index ) {
				cout << "마지막" << endl;
				Person clearObj = Person();
				arr[i] = clearObj;
			}
			else {
				arr[i] = arr[i + 1];
			}
		}
	}
}

Person.h

// https://whoishoo.tistory.com/13

#ifndef Person_H
#define Person_H

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


class Person {
	private:
		string name = "";
		Date birth ;
		double height;
		double weight;

	public :
		Person(); // 기본 생성자 
		Person( string name, Date birth, double h, double w ); // 생성자 오버라이드 
		void setName( string &name );
		void setBirth( Date date );
		void setHeight( double h );
		void setWeight( double w );

		string getName();
		Date getBirth();
		double getHeight();
		double getWeight();
		void viewData();
		void setPerson( Person& item );
};

#endif // !Person_H

Date.h

// Preprocessor
// ifndef, #define, 그리고 마지막 줄에 #endif가 있습니다.이건 헤더파일을 컴파일러가 호출할 때 여러번 호출되지 않게끔 하는 기능을 갖고 있습니다.
#ifndef Date_H
#define Date_H

#include <string>
#include <iostream>

using namespace std;
using std::string;


// 헤더에서는 사용할 클래스와 함수 즉 선언부와 구현부 중에 선언부만 외부에 공개 한다.
// 이후에 모듈을 만들어 외부에 배포하는 경우에는 모듈과  헤더만 주면 되기 때문이다. ( 캡슐화 )

class Date
{
	private : 
		int year = 0;
		int month = 0;
		int day = 0;

	public :
		Date();
		Date( int year, int month, int day ); // 헤더파일엔 프로토타입만 !  
		void setYear(int year);
		void setMonth(int month);
		void setDay(int day);
		double getYear();
		double getMonth();
		double getDay();

		string showDate();
};

#endif // Date
728x90
반응형

'C++' 카테고리의 다른 글

C++ 원형 LinkedList  (0) 2022.11.02
C++ Linked List ( 단방향 )  (0) 2022.11.01
C++ 클래스 생성 / 헤더파일.  (0) 2022.10.28
C++ 함수 포인터  (0) 2022.10.27
C++ 공용체 ( union )  (0) 2022.10.27