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 |