전체적인 코드 흐름
클라이언트 소켓을 생성하여 서버와 통신: 사용자가 서버로 메시지를 보내고 응답을 받음.
카드 정보를 관리: 카드 혜택, 이름, 회사, 연회비 등의 정보를 저장하는 Card 클래스를 통해 여러 카드를 관리하고, 조건에 맞는 카드를 추천하는 기능.
메뉴 기반 사용자 인터페이스: 사용자가 선택한 혜택에 맞춰 카드를 추천하거나 검색하는 기능을 제공.
사용자 설문조사: 사용자에게 질문을 통해 선호 혜택을 수집하고, 그에 따라 맞춤형 카드를 추천하는 방식.
1. 필요한 헤더 포함
#include <iostream>
#include <cstring>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <algorithm>
#include <unistd.h>
#include <limits> // numeric_limits 사용을 위해 추가
#include <set>
#include <string>
#include <sstream>
#include <map>
#include <vector>
#include <regex>
iostream: 표준 입출력 사용을 위해 포함.
cstring: 문자열 처리에 필요한 C 표준 라이브러리.
sys/socket.h, arpa/inet.h, unistd.h: 소켓 프로그래밍을 위한 헤더. 서버와의 통신을 위한 소켓 생성, 연결 등에 필요.
limits: std::numeric_limits 사용을 위해 포함, 버퍼 처리 등에서 필요.
set, map, vector, regex: STL 컨테이너와 정규 표현식을 사용하기 위해 포함. 카드를 저장하고, 혜택을 처리할 때 사용.
2. 텍스트 색상 정의
#define RED "\033[31m"
#define RED_BOLD "\033[1;31m"
// 여러 색상과 굵기 옵션을 정의
#define END "\033[0m"
터미널에서 텍스트 색상과 스타일을 변경하는 ANSI 코드 정의.
3. 카드 혜택 정보 저장 구조체
struct CardBenefit
{
string cardName;
string benefitType;
int benefitValue;
};
CardBenefit: 각 카드의 혜택 정보를 저장하는 구조체.
4. 성향 점수 구조체
struct BenefitScore
{
string benefitType;
int score;
};
사용자 설문조사 결과에 따라 혜택의 중요도를 점수로 저장하는 구조체.
5. 성향 점수를 비교하는 함수
bool compareScores(BenefitScore a, BenefitScore b)
{
return a.score > b.score;
}
성향 점수 리스트를 내림차순으로 정렬하기 위한 비교 함수.
6. 카드 혜택을 비교하는 함수
bool compareBenefits(CardBenefit a, CardBenefit b)
{
return a.benefitValue > b.benefitValue;
}
카드 혜택을 내림차순으로 정렬하기 위한 비교
7. 유효한 입력을 받을 때까지 반복하는 함수
int getValidInput()
{
int input;
while (true)
{
cin >> input;
if (input == 1 || input == 2)
{
break; // 입력값이 1 또는 2인 경우 루프 탈출
}
else
{
cout << "잘못된 입력입니다. 다시 입력하세요 (1. YES 2. NO): ";
continue;
}
}
return input;
}
사용자로부터 1 또는 2의 유효한 입력을 받을 때까지 반복.
8. Card 클래스
class Card
{
private:
int idx = 0; // 카드 인덱스
std::string name; // 카드명
std::string company; // 카드사
std::string annualFee; // 연회비
std::string preMonSpending; // 전월 실적
std::string benetype1; // 혜택1 타입
std::string bene1; // 혜택1 상세
std::string benetype2; // 혜택2 타입
std::string bene2; // 혜택2 상세
map<string, string> benefits; // 혜택 타입과 해당 이모지를 매핑한 맵
public:
// 생성자: 카드 객체 생성 시 필수 정보를 초기화
Card(const std::string &name, const std::string &company, const std::string &annualFee,
const std::string &previousMonthSpending, const std::string &benetype1, const std::string &bene1, const std::string &benetype2, const std::string &bene2)
: name(name), company(company), annualFee(annualFee),
preMonSpending(previousMonthSpending), benetype1(benetype1), bene1(bene1), benetype2(benetype2), bene2(bene2)
{
idx++; // 카드 생성 시마다 인덱스 증가
benefits = {
{"대중교통", "🚌 교통"},
{"쇼핑", "🛍️ 쇼핑"},
{"외식", "🍽️ 외식"},
{"의료", "🏥 의료"},
{"주유", "⛽ 주유"},
{"통신", "📞 통신"}};
}
// 카드명 반환
std::string getName() const { return name; }
std::string getCompany() const { return company; }
std::string getAnnualFee() const { return annualFee; }
std::string getPreviousMonthSpending() const { return preMonSpending; }
// 혜택 이름을 이모지로 대체하는 함수
string replaceBenefits(const string &inputText) const
{
string result = inputText;
for (const auto &pair : benefits)
{
// 정규 표현식을 사용해 혜택 이름을 이모지로 대체
regex pattern(pair.first);
result = regex_replace(result, pattern, pair.second);
}
return result;
}
// 사용자 선택 혜택과 일치하는지 확인하는 함수
bool isBenefitMatch(const std::vector<std::string> &userBenefits) const
{
return std::find(userBenefits.begin(), userBenefits.end(), benetype1) != userBenefits.end() ||
std::find(userBenefits.begin(), userBenefits.end(), benetype2) != userBenefits.end();
}
// 카드 정보를 출력하는 함수
void printCardInfo() const
{
std::string cmp_temp;
// 카드명과 카드사 출력
std::cout << " " << "┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ \n";
std::cout << " " << "┃ " << PURPLE_BOLD << name << END << " \n";
if (company == "KB국민카드")
{
cmp_temp = "국민카드";
std::cout << " " << "┃ " << ORANGE_BOLD << cmp_temp << END << " ┃\n";
}
else if (company == "신한카드" || company == "하나카드")
std::cout << " " << "┃ " << GREEN_BOLD << company << END << " ┃\n";
else if (company == "롯데카드")
std::cout << " " << "┃ " << RED_BOLD << company << END << " ┃\n";
else if (company == "삼성카드" || company == "우리카드")
std::cout << " " << "┃ " << BLUE_BOLD << company << END << " ┃\n";
std::cout << " " << "┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ \n";
// 혜택을 이모지로 변환하여 출력
string replacedBene1 = replaceBenefits(benetype1);
string replacedBene2 = replaceBenefits(benetype2);
std::cout << BROWN_BOLD
<< " " << replacedBene1
<< " " << bene1 << '\n'
<< " " << replacedBene2
<< " " << bene2 << END << '\n'
<< LGREEN_BOLD << " 연회비 "
<< annualFee << END << '\n'
<< LBLUE_BOLD << " 전월실적 "
<< preMonSpending << END << "\n──────────────────────────────────────────────────────────\n"
<< std::endl;
}
};
카드 정보를 저장하고, 해당 정보를 이모지로 대체하거나 출력하는 기능을 담당하는 클래스.
9. 문자열을 구분자로 분리하는 함수
std::vector<std::string> split(const std::string &str, char delimiter)
{
std::vector<std::string> tokens;
std::stringstream ss(str);
std::string token;
while (std::getline(ss, token, delimiter))
{
tokens.push_back(token);
}
return tokens;
}
입력된 문자열을 주어진 구분자(delimiter)로 분리하여 벡터에 저장하는 함수입니다.
10. 메인 함수
int main()
{
int port;
std::cout << "연결할 서버 포트를 입력하세요: ";
std::cin >> port;
if (std::cin.fail() || port <= 0 || port > 65535)
{
std::cerr << "유효하지 않은 포트 번호입니다. 1과 65535 사이의 값을 입력하세요.\n";
return 1;
}
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
int client_socket = socket(AF_INET, SOCK_STREAM, 0);
if (client_socket == -1)
{
std::cerr << "소켓 생성에 실패했습니다.\n";
return 1;
}
sockaddr_in server_addr{};
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
if (inet_pton(AF_INET, SERVER_IP, &server_addr.sin_addr) <= 0)
{
std::cerr << "유효하지 않은 주소입니다.\n";
return 1;
}
if (connect(client_socket, (sockaddr *)&server_addr, sizeof(server_addr)) < 0)
{
std::cerr << "서버 연결에 실패했습니다.\n";
return 1;
}
std::cout << "서버에 연결되었습니다.\n";
bool inputMode = false;
bool sqlMode = true;
std::vector<Card> cards; // Card 객체를 저장할 벡터
std::string user_input;
while (true)
{
// 여러 루프와 조건문을 통해 입력을 처리하는 로직이 포함되어 있음
// ...
}
close(client_socket);
return 0;
}
소켓을 통해 서버와 연결하고, 사용자로부터 입력을 받아 처리하는 메인 로직입니다. 여러 조건에 따라 카드 정보를 처리하고, 이를 출력하는 로직이 포함
전체 로직
#include <iostream>
#include <cstring>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <algorithm>
#include <unistd.h>
#include <limits> // numeric_limits 사용을 위해 추가
#include <set>
#include <string>
#include <sstream>
#include <map>
#include <vector>
#include <regex>
using namespace std;
#define RED "\033[31m"
#define RED_BOLD "\033[1;31m"
#define ORANGE "\033[38;5;214m"
#define ORANGE_BOLD "\033[1;38;5;214m"
#define YELLOW "\033[33m"
#define YELLOW_BOLD "\033[1;33m"
#define GREEN "\033[32m"
#define GREEN_BOLD "\033[1;32m"
#define BLUE "\033[34m"
#define BLUE_BOLD "\033[1;34m"
#define PURPLE "\033[35m"
#define PURPLE_BOLD "\033[1;35m"
#define PINK "\033[38;5;213m"
#define PINK_BOLD "\033[1;38;5;213m"
#define BROWN "\033[38;5;130m"
#define BROWN_BOLD "\033[1;38;5;130m"
#define LBLUE "\033[38;5;153m" // 연한 파란색
#define LBLUE_BOLD "\033[1;38;5;153m"
#define LGREEN "\033[38;5;154m" // 연한 초록색
#define LGREEN_BOLD "\033[1;38;5;154m" // 연한 초록색
#define CHARCOAL "\033[38;5;240m" // 차콜색 (어두운 회색)
#define CHARCOAL_BOLD "\033[1;38;5;240m" // 차콜색 (굵은 스타일)
#define END "\033[0m"
// 카드 혜택 정보를 저장하는 구조체
struct CardBenefit
{
string cardName;
string benefitType;
int benefitValue;
};
// 성향 점수 구조체
struct BenefitScore
{
string benefitType;
int score;
};
// 성향 점수를 기준으로 정렬하는 함수
bool compareScores(BenefitScore a, BenefitScore b)
{
return a.score > b.score;
}
// 혜택 값을 기준으로 정렬하는 함수
bool compareBenefits(CardBenefit a, CardBenefit b)
{
return a.benefitValue > b.benefitValue;
}
// 올바른 입력을 받을 때까지 반복하는 함수
int getValidInput()
{
int input;
while (true)
{
cin >> input;
if (input == 1 || input == 2)
{
break; // 입력값이 1 또는 2인 경우 루프 탈출
}
else
{
cout << "잘못된 입력입니다. 다시 입력하세요 (1. YES 2. NO): ";
continue;
}
}
return input;
}
constexpr int BUF_SIZE = 1024;
const char *SERVER_IP = "127.0.0.1";
class Card
{
private:
int idx = 0;
std::string name; // 카드명
std::string company; // 카드사
std::string annualFee; // 연회비
std::string preMonSpending; // 전월 실적
std::string benetype1; // 혜택1 타입
std::string bene1; // 혜택1 상세
std::string benetype2; // 혜택2 타입
std::string bene2; // 혜택2 상세
map<string, string> benefits;
public:
// 생성자
Card(const std::string &name, const std::string &company, const std::string &annualFee,
const std::string &previousMonthSpending, const std::string &benetype1, const std::string &bene1, const std::string &benetype2, const std::string &bene2)
: name(name), company(company), annualFee(annualFee),
preMonSpending(previousMonthSpending), benetype1(benetype1), bene1(bene1), benetype2(benetype2), bene2(bene2)
{
idx++;
benefits = {
{"대중교통", "🚌 교통"},
{"쇼핑", "🛍️ 쇼핑"},
{"외식", "🍽️ 외식"},
{"의료", "🏥 의료"},
{"주유", "⛽ 주유"},
{"통신", "📞 통신"}};
// 🎁
}
// 접근 메서드
std::string getName() const { return name; }
std::string getCompany() const { return company; }
std::string getAnnualFee() const { return annualFee; }
std::string getPreviousMonthSpending() const { return preMonSpending; }
// 텍스트 대치 함수 선언 및 정의
string replaceBenefits(const string &inputText) const
{
string result = inputText;
// 반복문을 이용해 map의 모든 키워드와 그에 대응하는 이모지를 대치
for (const auto &pair : benefits)
{
// 키워드를 정규 표현식으로 사용하여 전체 문자열에서 대체
regex pattern(pair.first);
result = regex_replace(result, pattern, pair.second);
}
return result;
}
// 필터링 메서드: 사용자가 선택한 혜택과 일치하는지 확인
bool isBenefitMatch(const std::vector<std::string> &userBenefits) const
{
return std::find(userBenefits.begin(), userBenefits.end(), benetype1) != userBenefits.end() ||
std::find(userBenefits.begin(), userBenefits.end(), benetype2) != userBenefits.end();
}
// 카드 정보 출력 함수
void printCardInfo() const
{
std::string cmp_temp;
// std::cout << "-----------------------------------------------------------------------------------------------\n";
std::cout << " " << "┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ \n";
std::cout << " " << "┃ " << PURPLE_BOLD << name << END << " \n";
// 카드사의 이름에 따라 출력 색상 설정 (중복 코드 간소화)
if (company == "KB국민카드")
{
cmp_temp = "국민카드";
std::cout << " " << "┃ " << ORANGE_BOLD << cmp_temp << END << " ┃\n";
}
else if (company == "신한카드" || company == "하나카드")
std::cout << " " << "┃ " << GREEN_BOLD << company << END << " ┃\n";
else if (company == "롯데카드")
std::cout << " " << "┃ " << RED_BOLD << company << END << " ┃\n";
else if (company == "삼성카드" || company == "우리카드")
std::cout << " " << "┃ " << BLUE_BOLD << company << END << " ┃\n";
std::cout << " " << "┃ ┃\n";
std::cout << " " << "┃ ■■■■■■ ┃\n";
std::cout << " " << "┃ ■■■■■■ ┃\n";
std::cout << " " << "┃ ┃\n";
std::cout << " " << "┃ 0000 0000 1234 1234 1234 ┃\n";
std::cout << " " << "┃ ┃\n";
std::cout << " " << "┃ ┃\n";
std::cout << " " << "┃ year 11/28 ┃\n";
std::cout << " " << "┃ ┃\n";
std::cout << " " << "┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ \n";
// std::cout << PURPLE_BOLD << " " << name << END << '\t';
// 혜택 정보를 이모지로 대체
string replacedBene1 = replaceBenefits(benetype1);
string replacedBene2 = replaceBenefits(benetype2);
std::cout << BROWN_BOLD
<< " " << replacedBene1
<< " " << bene1 << '\n'
<< " " << replacedBene2
<< " " << bene2 << END << '\n'
<< LGREEN_BOLD << " 연회비 "
<< annualFee << END << '\n'
<< LBLUE_BOLD << " 전월실적 "
<< preMonSpending << END << "\n──────────────────────────────────────────────────────────\n"
<< std::endl;
}
};
// 문자열을 구분자로 분리하는 함수
std::vector<std::string> split(const std::string &str, char delimiter)
{
std::vector<std::string> tokens;
std::stringstream ss(str);
std::string token;
while (std::getline(ss, token, delimiter))
{
tokens.push_back(token);
}
return tokens;
}
int main()
{
// 포트 입력 받기
int port;
std::cout << "연결할 서버 포트를 입력하세요: ";
std::cin >> port;
// 유효성 검사
if (std::cin.fail() || port <= 0 || port > 65535)
{
std::cerr << "유효하지 않은 포트 번호입니다. 1과 65535 사이의 값을 입력하세요.\n";
return 1;
}
// 입력 버퍼 클리어 (포트 입력 후 남은 개행 제거)
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
// 소켓 생성
int client_socket = socket(AF_INET, SOCK_STREAM, 0);
if (client_socket == -1)
{
std::cerr << "소켓 생성에 실패했습니다.\n";
return 1;
}
// 서버 주소 설정
sockaddr_in server_addr{};
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
if (inet_pton(AF_INET, SERVER_IP, &server_addr.sin_addr) <= 0)
{
std::cerr << "유효하지 않은 주소입니다.\n";
return 1;
}
// 서버에 연결
if (connect(client_socket, (sockaddr *)&server_addr, sizeof(server_addr)) < 0)
{
std::cerr << "서버 연결에 실패했습니다.\n";
return 1;
}
std::cout << "서버에 연결되었습니다.\n";
bool inputMode = false;
bool sqlMode = true;
std::vector<Card> cards; // Card 객체를 저장할 벡터
std::string user_input;
// 메시지 송수신 루프
while (true)
{
/* 0. 카드 클래스 생성 및 데이터 가져오기 */
while (!inputMode && sqlMode)
{
char sqlBuffer[10000]; // recv를 위한 버퍼
// 카드사 목록
std::vector<std::string> card_companies = {"KB국민카드", "신한카드", "우리카드", "하나카드", "롯데카드", "삼성카드"};
for (const auto &company : card_companies)
{
// 쿼리 문자열 생성
std::string modified_message = "query:SELECT name AS '카드명', corp_name AS '카드사', annual AS '연회비', month AS '전월실적', "
"bene1_type AS '혜택1', bene1 AS '혜택1 상세', bene2_type AS '혜택2', bene2 AS '혜택2 상세' "
"FROM card_project.Card WHERE corp_name = '" +
company + "'";
// 서버에 쿼리 전송
send(client_socket, modified_message.c_str(), modified_message.length(), 0);
// 서버에서 응답 수신
ssize_t bytes_received = recv(client_socket, sqlBuffer, sizeof(sqlBuffer) - 1, 0);
if (bytes_received <= 0)
{
std::cerr << "서버가 연결을 끊었거나 오류가 발생했습니다.\n";
break;
}
sqlBuffer[bytes_received] = '\0'; // 문자열 종료 추가
// 문자열 스트림을 사용해 한 줄씩 데이터를 읽고 처리
std::stringstream ss(sqlBuffer);
std::string line;
while (std::getline(ss, line))
{
if (!line.empty())
{
std::vector<std::string> parts = split(line, '_');
if (parts.size() == 8)
{
Card card(parts[0], parts[1], parts[2], parts[3], parts[4], parts[5], parts[6], parts[7]);
cards.push_back(card);
}
}
}
}
// 모든 Card 객체의 정보 출력
for (const auto &card : cards)
{
card.printCardInfo();
}
sqlMode = false; // sqlMode 종료
}
/* 1. 메인 화면 */
while (!inputMode && !sqlMode)
{
// 1-1. 인트로 화면
system("clear");
std::cout << "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣤⣤⣤⣄⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀\n";
std::cout << "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⡷⡵⣳⢝⡟⡷⣦⡀⠀⠀⠀⢀⣠⡴⡴⣦⢶⣴⣤⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀\n";
std::cout << "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠛⢼⡫⣞⢽⣪⡻⣧⢔⣼⣫⡳⣝⢞⡵⣳⢵⣝⠇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀\n";
std::cout << "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠈⠁⠁⢁⡕⢭⠀⠑⠙⠊⠋⠊⠑⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀\n";
std::cout << "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠀⠄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⠏⠀⠸⡂⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀\n";
std::cout << "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣰⢳⡹⣫⢳⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣀⡀⢠⠞⠁⠀⠀⠈⢧⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠠⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀\n";
std::cout << "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⡕⡕⠥⡨⢣⡝⣵⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣟⡽⣹⡫⣟⢄⠀⠀⠀⢀⡼⡦⣆⢄⠀⠀⠀⠀⠀⠀⠀⠀⠑⡄⠀⠀⠀⡀⠐⠀⠀⠀⠀⠀⠀⠀⢀⠀⡀⢀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀\n";
std::cout << "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡳⣝⠌⡆⠑⡢⢚⢴⢝⡤⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢹⣮⢳⡝⣮⢳⡍⠀⠀⠀⣾⣫⢞⡮⣳⣅⠀⠀⠀⠀⠀⠀⠀⠀⡽⣒⢗⠊⠀⣀⡠⠰⠔⠜⠒⠋⠋⠫⠫⣝⢭⡫⡳⡲⣄⡀⠀⠀⠀⠀⠀⠀⠀⠀\n";
std::cout << "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢨⡳⡕⢌⠪⢀⠈⢆⠱⡱⣝⢦⣀⢆⡔⣤⢢⡢⡲⡔⡦⣢⡀⠀⠀⠀⠀⠀⠀⠙⠮⠳⠝⠊⠀⠀⠀⠀⠻⣮⡳⣝⢮⡞⠀⠀⠀⠀⠀⠀⡠⠊⠃⠙⢦⠀⠈⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠪⢝⢮⡪⣳⢄⠀⠀⠀⠀⠀⠀⠀\n";
std::cout << "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣞⢜⠕⡌⢂⠀⠂⠄⠑⡔⠱⠕⠵⡙⢎⢎⠣⣋⠚⡜⠪⣎⢽⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠁⠛⠘⠁⠀⠀⠀⠀⠀⠀⠁⠀⠀⠀⠀⠀⠡⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⣗⢵⡱⢧⠀⠀⠀⠀⠀⠀⠀\n";
std::cout << "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡀⢠⣀⢦⢬⡚⡮⡣⢏⢌⡊⠠⠈⠄⠈⠄⡈⠑⡉⠊⠜⢀⠃⠑⡈⢈⠊⠒⠘⠪⠂⠀⠀⡐⣠⡂⠄⠀⠀⠀⠀⡐⣠⡂⠄⠀⠀⢀⠀⡀⠀⠀⠀⠀⢀⠀⠀⠀⠀⠀⠀⠀⠀⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢮⡪⡺⡕⠀⠀⠀⠀⠀⠀⠀\n";
std::cout << "⠀⠀⠀⠀⠀⠀⠀⠀⢀⢢⢎⢞⢵⠱⡣⢣⢙⢌⠢⡑⠂⢐⣀⡁⣈⢐⠀⡐⠠⡀⢁⠂⠄⢨⢗⢝⢎⢏⡫⣛⠆⠐⣠⡢⣰⢣⠯⣤⣨⡀⢂⡔⡤⡳⣝⢄⣢⠀⠄⢶⢦⠁⠀⡀⢱⠴⡄⢁⠀⠄⡐⢀⠀⡂⠠⠀⡀⢂⢐⢀⢂⡐⢀⠀⡐⠀⠄⠀⢀⡗⣝⢼⠁⠀⠀⠀⠀⠀⠀⠀\n";
std::cout << "⠀⠀⠀⠀⠀⠀⠀⠀⢸⣣⡋⡪⠢⡱⠈⠂⠡⠀⠂⠄⠁⠽⣌⢯⡪⣫⢻⠀⢼⡹⡅⠐⡀⢨⡳⣝⠀⠢⠠⢀⠀⠂⠘⡸⣕⠳⣓⢖⡑⢁⠘⠊⣺⢪⢎⡃⠋⣢⢌⡗⣵⠀⡱⡴⣜⢝⢮⠴⣄⢸⣙⡇⣸⢻⠄⢀⠘⠯⠹⠍⣧⢫⡃⢐⡏⣟⠀⠀⡼⡪⣎⠃⠀⠀⠀⠀⠀⠀⠀⠀\n";
std::cout << "⠀⠀⠀⠀⠀⠀⠀⠀⠘⢦⡳⣌⡪⢢⢑⢌⠠⠁⠌⠠⠁⡤⡤⡤⡔⢧⡻⡀⢸⢎⢗⡝⠆⠐⢧⢝⢝⢝⢝⠕⠇⠈⢴⢫⠎⢁⠈⠳⡹⡆⠀⡵⣣⡓⠩⣛⢦⡑⠑⣝⢼⠀⡈⢊⡮⡳⣑⠉⣢⢜⢮⠆⢼⡱⡃⠀⣲⠲⡖⢶⡱⣝⠆⢐⡝⣮⠀⡼⣣⠫⠂⠀⠀⠀⠀⠀⠀⠀⠀⠀\n";
std::cout << "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⠬⡳⡕⢧⣊⠪⡢⢌⡐⠀⠚⠘⠊⠚⡵⣹⠀⢸⡣⡇⠠⠈⢠⠦⡤⢦⠤⡦⣔⡌⠠⢠⡕⡴⡔⡴⣔⢬⡄⠀⠙⠂⠄⠀⢈⢑⣤⠀⡑⠉⠄⢠⢏⢮⠓⢝⢵⡌⢑⢗⡇⢸⢎⠇⠀⣝⢮⡣⡴⡤⣤⡂⠠⣏⢾⠀⡯⠊⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀\n";
std::cout << "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠚⢜⡳⡪⡆⢕⠈⠄⠡⠈⠄⠙⠈⠄⡀⢉⠠⠀⠡⠈⢃⠙⠘⠑⠑⠈⠊⠀⠈⠊⠊⣺⠪⠊⠊⠂⠈⠀⠀⠀⠀⠀⠰⡳⠦⡦⠐⠀⠀⠉⠂⠀⠀⠑⠁⠀⠁⠁⠈⠁⠁⠀⠘⢀⠉⠊⠘⠀⡁⢀⣅⣡⠐⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀\n";
std::cout << "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢹⡪⡎⢪⠂⡈⠄⠡⠈⢄⠡⡂⢔⠠⡀⠡⠀⠡⢈⢍⠹⡫⣏⠀⠀⠀⠀⠀⠀⠑⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠂⠐⠀⠀⠂⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡴⡫⠊⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀\n";
std::cout << "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠸⣜⡕⡡⠃⠄⠈⢄⠱⡈⣎⢜⣔⢅⠣⡊⢆⠥⡀⢌⡊⢺⢜⣇⠀⠀⡀⢀⠀⡀⢀⠀⠄⡀⢀⠀⢢⠐⡀⢀⠀⡀⢀⠂⡆⢀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⢜⠕⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀\n";
std::cout << "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠨⡮⣪⠨⡃⢈⢔⠡⡣⡞⣜⠕⠵⢩⢏⢞⢦⡣⡪⡢⡑⢅⡧⣝⠀⠀⣸⠑⡹⣸⠑⠙⣜⠈⡗⠀⡳⣸⢑⠗⡜⠑⡁⢹⡑⢁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡔⠮⠁⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀\n";
std::cout << "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠐⡯⣪⠢⡑⡅⣪⠺⣕⠝⠀⠀⠀⠀⠈⠁⠃⠹⢪⢝⢎⢗⡕⠃⠀⠀⡮⠉⠁⠊⠀⠀⠉⠉⠉⠉⠁⠈⠑⠁⠙⠉⠁⠈⠉⠂⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⢔⠜⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀\n";
std::cout << "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢫⡺⣢⢕⢮⡣⠛⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡠⠂⠊⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀\n";
std::cout << "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠑⠑⠃⠃⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀\n";
// std::cin.get()을 사용하여 아무 키나 입력 받기
std::cout << "카드 추천 체리 서비스에 오신걸 환영합니다.\n";
std::cout << "계속하려면 아무 키나 누르세요.";
std::cin.get(); // 사용자로부터 아무 키나 입력받음
system("clear");
// 1-2.메뉴 선택 화면
char buffer[BUF_SIZE];
bool menu = true;
int menuIdx = 0; // 0 : 메뉴 선택, 1 : 카드 검색, 2: 카드 추천
std::set<std::string> valid_inputs;
while (menu)
{
std::string result; // 사용자가 선택한 혜택
while (menuIdx == 0) // 메뉴 선택
{
system("clear");
valid_inputs = {"검색", "카드 검색", "카드검색", "1", "추천", "카드 추천", "카드추천", "2"}; // 유효한 입력값을 모아놓은 set
std::cout << "┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\t";
std::cout << "┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n";
std::cout << "┃ ┃\t";
std::cout << "┃ ┃\n";
std::cout << "┃ 맞춤 혜택으로 직접 찾기 ┃\t";
std::cout << "┃ 1분 테스트로 추천 받기 ┃\n";
std::cout << "┃ 🔍 카드 검색 ┃\t";
std::cout << "┃ 📱 카드추천 테스트 ┃\n";
std::cout << "┃ ┃\t";
std::cout << "┃ ┃\n";
std::cout << "┃ [1.맞춤 카드 바로가기] ┃\t";
std::cout << "┃ [2.카드추천 테스트 바로가기] ┃\n";
std::cout << "┃ ┃\t";
std::cout << "┃ ┃\n";
// 하단 라인
std::cout << "┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛\t";
std::cout << "┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛\n";
while (true)
{
std::cout << "메뉴를 선택하세요 : ";
std::getline(std::cin, user_input); // 사용자 입력 받기
if (valid_inputs.find(user_input) != valid_inputs.end())
{
if (user_input == "1" || user_input == "검색" || user_input == "카드 검색" || user_input == "카드검색")
{
menuIdx = 1;
break;
}
else if (user_input == "2" || user_input == "추천" || user_input == "카드 추천" || user_input == "카드추천")
{
menuIdx = 2;
break;
}
}
else // 유효하지 않은 입력이면 다시 요청
{
std::cout << "잘못된 입력입니다. 다시 시도해주세요." << std::endl;
continue;
}
}
}
while (menuIdx == 1)
{
system("clear");
std::vector<std::string> userSelectedBenefits; // 사용자가 선택한 혜택 리스트
/* 유효한 입력값을 모아놓은 set */
valid_inputs = {"대중교통", "교통", "쇼핑", "외식", "의료", "주유", "통신",
"1", "2", "3", "4", "5", "6", "back"};
std::cout << "┏━━━━━━━━━━━━━━━━━━━━━━━━━━┓\t";
std::cout << "┏━━━━━━━━━━━━━━━━━━━━━━━━━━┓\t";
std::cout << "┏━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n";
std::cout << "┃ 1.대중교통 ┃\t";
std::cout << "┃ 2. 쇼핑 ┃\t";
std::cout << "┃ 3. 외식 ┃\n";
std::cout << "┃ 🚌 ┃\t";
std::cout << "┃ 🛍️ ┃\t";
std::cout << "┃ 🍽️ ┃\n";
std::cout << "┗━━━━━━━━━━━━━━━━━━━━━━━━━━┛\t";
std::cout << "┗━━━━━━━━━━━━━━━━━━━━━━━━━━┛\t";
std::cout << "┗━━━━━━━━━━━━━━━━━━━━━━━━━━┛\n\n";
std::cout << "┏━━━━━━━━━━━━━━━━━━━━━━━━━━┓\t";
std::cout << "┏━━━━━━━━━━━━━━━━━━━━━━━━━━┓\t";
std::cout << "┏━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n";
std::cout << "┃ 4. 의료 ┃\t";
std::cout << "┃ 5. 주유 ┃\t";
std::cout << "┃ 6. 통신 ┃\n";
std::cout << "┃ 🏥 ┃\t";
std::cout << "┃ ⛽ ┃\t";
std::cout << "┃ 📞 ┃\n";
std::cout << "┗━━━━━━━━━━━━━━━━━━━━━━━━━━┛\t";
std::cout << "┗━━━━━━━━━━━━━━━━━━━━━━━━━━┛\t";
std::cout << "┗━━━━━━━━━━━━━━━━━━━━━━━━━━┛\n";
std::cout << "이전 메뉴로 돌아가기 : 'back' 입력\n";
// 선호 혜택 선택
while (menuIdx == 1)
{
std::cout << "선호하시는 혜택을 선택하세요 : ";
std::getline(std::cin, user_input); // 사용자 입력 받기
if (valid_inputs.find(user_input) != valid_inputs.end())
{
// 유효한 입력이면 대응하는 결과를 설정하고 반복 종료
if (user_input == "대중교통" || user_input == "교통" || user_input == "1")
{
result = "대중교통";
break;
}
else if (user_input == "2" || user_input == "쇼핑")
{
result = "쇼핑";
break;
}
else if (user_input == "3" || user_input == "외식")
{
result = "외식";
break;
}
else if (user_input == "4" || user_input == "의료")
{
result = "의료";
break;
}
else if (user_input == "5" || user_input == "주유")
{
result = "주유";
break;
}
else if (user_input == "6" || user_input == "통신")
{
result = "통신";
break;
}
else if (user_input == "back")
{
menuIdx = 0;
break;
}
}
else // 유효하지 않은 입력이면 다시 요청
{
std::cout << "잘못된 입력입니다. 다시 시도해주세요." << std::endl;
continue;
}
}
// 선호 혜택 결과 출력
while (menuIdx == 1)
{
system("clear");
userSelectedBenefits.push_back(result); // 사용자가 입력한 혜택을 리스트에 추가
for (const auto &card : cards)
{
if (card.isBenefitMatch(userSelectedBenefits))
{
card.printCardInfo();
}
}
std::cout << "\n다른 혜택을 선택하시려면 'back', 메인 메뉴로 돌아가시려면 'main'을 입력하세요.\n>>";
std::cin >> user_input;
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
if (user_input == "back")
{
break; // 입력을 끝내기 위해 '끝'을 입력
}
else if (user_input == "main")
{
menuIdx = 0;
break; // 입력을 끝내기 위해 '끝'을 입력
}
}
}
while (menuIdx == 2)
{
std::vector<std::string> userSelectedBenefits; // 사용자가 선택한 혜택 리스트
// 각 혜택의 점수를 저장할 변수 초기화
map<string, int> benefitScores = {
{"commute", 0}, // 교통
{"shopping", 0}, // 쇼핑
{"dining", 0}, // 외식
{"medical", 0}, // 의료
{"fuel", 0}, // 주유
{"telecom", 0} // 통신
};
int answer;
system("clear");
std::cout << "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n";
std::cout << "01/18" << " ██░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ " << "5.6%\n";
cout << "\n🍒 운전을 많이 하시나요?\n (1. YES 2. NO) >> ";
answer = getValidInput();
if (answer == 1)
{
benefitScores["commute"]++;
}
system("clear");
std::cout << "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n";
std::cout << "02/18" << " ████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ " << "11.1%\n";
cout << "\n🍒 외식을 자주 하시나요?\n (1. YES 2. NO) >> ";
answer = getValidInput();
if (answer == 1)
{
benefitScores["dining"]++;
}
system("clear");
std::cout << "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n";
std::cout << "03/18" << " ██████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ " << "16.7%\n";
cout << "\n🍒 대중교통을 자주 이용하시나요?\n (1. YES 2. NO) >> ";
answer = getValidInput();
if (answer == 1)
{
benefitScores["commute"]++;
}
system("clear");
std::cout << "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n";
std::cout << "04/18" << " ████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░ " << "22.2%\n";
cout << "\n🍒 고속도로를 갈 일이 많으신가요?\n (1. YES 2. NO) >> ";
answer = getValidInput();
if (answer == 1)
{
benefitScores["commute"]++;
}
system("clear");
std::cout << "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n";
std::cout << "05/18" << " ██████████░░░░░░░░░░░░░░░░░░░░░░░░░░ " << "27.8%\n";
cout << "\n🍒 핸드폰 요금 부담이 크신가요?\n (1. YES 2. NO) >> ";
answer = getValidInput();
if (answer == 1)
{
benefitScores["telecom"]++;
}
system("clear");
std::cout << "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n";
std::cout << "06/18" << " ████████████░░░░░░░░░░░░░░░░░░░░░░░░ " << "33.3%\n";
cout << "\n🍒 음식 배달을 자주 시키시나요?\n (1. YES 2. NO) >> ";
answer = getValidInput();
if (answer == 1)
{
benefitScores["dining"]++;
}
system("clear");
std::cout << "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n";
std::cout << "07/18" << " ██████████████░░░░░░░░░░░░░░░░░░░░░░ " << "38.9%\n";
cout << "\n🍒 주유비 할인이 필요하신가요?\n (1. YES 2. NO) >> ";
answer = getValidInput();
if (answer == 1)
{
benefitScores["fuel"]++;
}
system("clear");
std::cout << "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n";
std::cout << "08/18" << " ████████████████░░░░░░░░░░░░░░░░░░░░ " << "44.4%\n";
cout << "\n🍒 카페를 자주 가시나요?\n (1. YES 2. NO) >> ";
answer = getValidInput();
if (answer == 1)
{
benefitScores["dining"]++;
}
system("clear");
std::cout << "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n";
std::cout << "09/18" << " █████████████████░░░░░░░░░░░░░░░░░░░ " << "50.0%\n";
cout << "\n🍒 인터넷 비용 할인이 필요하신가요?\n (1. YES 2. NO) >> ";
answer = getValidInput();
if (answer == 1)
{
benefitScores["telecom"]++;
}
system("clear");
std::cout << "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n";
std::cout << "10/18" << " ████████████████████░░░░░░░░░░░░░░░░ " << "55.6%\n";
cout << "\n🍒 쇼핑을 자주 하시나요?\n (1. YES 2. NO) >> ";
answer = getValidInput();
if (answer == 1)
{
benefitScores["shopping"]++;
}
system("clear");
std::cout << "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n";
std::cout << "11/18" << " ██████████████████████░░░░░░░░░░░░░░ " << "61.1%\n";
cout << "\n🍒 통신 요금 할인이 필요하신가요?\n (1. YES 2. NO) >> ";
answer = getValidInput();
if (answer == 1)
{
benefitScores["telecom"]++;
}
system("clear");
std::cout << "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n";
std::cout << "12/18" << " ████████████████████████░░░░░░░░░░░░ " << "66.7%\n";
cout << "\n🍒 온라인 쇼핑을 많이 이용하시나요?\n (1. YES 2. NO) >> ";
answer = getValidInput();
if (answer == 1)
{
benefitScores["shopping"]++;
}
system("clear");
std::cout << "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n";
std::cout << "13/18" << " ██████████████████████████░░░░░░░░░░ " << "72.2%\n";
cout << "\n🍒 백화점 할인 혜택이 필요하신가요?\n (1. YES 2. NO) >> ";
answer = getValidInput();
if (answer == 1)
{
benefitScores["shopping"]++;
}
system("clear");
std::cout << "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n";
std::cout << "14/18" << " ████████████████████████████░░░░░░░░ " << "77.8%\n";
cout << "\n🍒 주기적으로 병원에 방문 하시나요?\n (1. YES 2. NO) >> ";
answer = getValidInput();
if (answer == 1)
{
benefitScores["medical"]++;
}
system("clear");
std::cout << "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n";
std::cout << "15/18" << " ██████████████████████████████░░░░░░ " << "83.3%\n";
cout << "\n🍒 자동차 유지비 절약이 필요하신가요?\n (1. YES 2. NO) >> ";
answer = getValidInput();
if (answer == 1)
{
benefitScores["fuel"]++;
}
system("clear");
std::cout << "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n";
std::cout << "16/18" << " ████████████████████████████████░░░░ " << "88.9%\n";
cout << "\n🍒 피부시술에 관심이 많으시나요?\n (1. YES 2. NO) >> ";
answer = getValidInput();
if (answer == 1)
{
benefitScores["medical"]++;
}
system("clear");
std::cout << "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n";
std::cout << "17/18" << " ██████████████████████████████████░░ " << "94.4%\n";
cout << "\n🍒 건강검진 비용이 부담되시나요?\n (1. YES 2. NO) >> ";
answer = getValidInput();
if (answer == 1)
{
benefitScores["medical"]++;
}
system("clear");
std::cout << "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n";
std::cout << "18/18" << " ████████████████████████████████████ " << "99.6%\n";
cout << "\n🍒 주유를 자주 하시나요?\n (1. YES 2. NO) >> ";
answer = getValidInput();
if (answer == 1)
{
benefitScores["fuel"]++;
}
// 2. 성향 점수를 벡터에 넣고 정렬
vector<BenefitScore> scores;
for (auto &pair : benefitScores)
{
scores.push_back({pair.first, pair.second});
}
sort(scores.begin(), scores.end(), compareScores);
// 3. 가장 높은 성향에 따라 카드 추천
string selectedBenefit = scores[0].benefitType; // 가장 높은 성향 추출
// std::cout << selectedBenefit;
// 유효한 입력이면 대응하는 결과를 설정하고 반복 종료
if (selectedBenefit == "commute")
{
result = "대중교통";
}
else if (selectedBenefit == "shopping")
{
result = "쇼핑";
}
else if (selectedBenefit == "dining")
{
result = "외식";
}
else if (selectedBenefit == "medical")
{
result = "의료";
}
else if (selectedBenefit == "fuel")
{
result = "주유";
}
else if (selectedBenefit == "telecom")
{
result = "통신";
}
system("clear");
userSelectedBenefits.push_back(result); // 사용자가 입력한 혜택을 리스트에 추가
// TOP3 출력
// "query:" 접두사 추가
std::string modified_message = "query:SELECT rb.card_name AS 카드명, rb.corp_name AS 카드사, c.annual AS 연회비, c.month AS 전월실적, c.bene1_type AS '혜택1', c.bene1 AS '혜택1 상세', c.bene2_type AS '혜택2', c.bene2 AS '혜택2 상세' FROM card_project.Rank_Benefit rb JOIN card_project.Card c ON rb.card_name = c.name WHERE rb.type = '" + result + "'";
send(client_socket, modified_message.c_str(), modified_message.length(), 0);
std::cout << std::endl;
ssize_t bytes_received = recv(client_socket, buffer, 10000, 0);
if (bytes_received <= 0)
{
std::cerr << "서버가 연결을 끊었거나 오류가 발생했습니다.\n";
break;
}
buffer[bytes_received] = '\0';
std::vector<Card> card_temp; // Card 객체를 저장할 벡터
// 문자열 스트림을 사용해 한 줄씩 데이터를 읽고 처리
std::stringstream ss(buffer);
std::string line;
while (std::getline(ss, line))
{
if (!line.empty())
{
std::vector<std::string> parts = split(line, '_');
// 디버깅: line과 parts 크기 출력
std::cout << "Processing line: " << line << std::endl;
std::cout << "Parts size: " << parts.size() << std::endl;
if (parts.size() == 8)
{
Card card1(parts[0], parts[1], parts[2], parts[3], parts[4], parts[5], parts[6], parts[7]);
card_temp.push_back(card1);
}
else
{
std::cout << "Warning: Unexpected number of parts (" << parts.size() << ") in line: " << line << std::endl;
}
}
}
system("clear");
std::cout << "🍒 고객님께 " + result + " 혜택을 추천드려요!\n🍒 " + result + " 혜택을 제공하는 카드중에 가장 인기 있는 3개의 카드를 보여드릴게요.\n\n";
// 모든 Card 객체의 정보 출력
for (const auto &card1 : card_temp)
{
card1.printCardInfo();
}
// 선호 혜택 결과 출력
while (menuIdx == 2)
{
std::cout << "\n다시 하시려면 'back', 메인 메뉴로 돌아가시려면 'main'을 입력하세요.\n>>";
std::cin >> user_input;
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
if (user_input == "back")
{
break; // 입력을 끝내기 위해 '끝'을 입력
}
else if (user_input == "main")
{
menuIdx = 0;
break; // 입력을 끝내기 위해 '끝'을 입력
}
}
}
continue;
}
inputMode = true;
menu = false;
}
/* 일반 메시지 전송 모드로 전환 */
while (inputMode)
{
char buffer[BUF_SIZE];
// system("clear");
std::cout << "서버로 보낼 메시지를 입력하세요 ('exit'을 입력하면 종료합니다): ";
std::getline(std::cin, user_input);
// 빈 입력에 대한 처리: 사용자가 엔터만 입력하면 다시 입력 요구
if (user_input.empty())
{
std::cout << "입력 값이 비어 있습니다. 다시 입력해주세요.\n";
continue; // 루프의 처음으로 돌아가 다시 입력 받음
}
// 'exit' 입력 시 일반 메시지 모드 종료
if (user_input == "exit")
{
break; // 일반 메시지 모드 종료
}
// 일반 메시지 전송
if (send(client_socket, user_input.c_str(), user_input.length(), 0) == -1)
{
std::cerr << "메시지 전송에 실패했습니다.\n";
return 1;
}
std::cout << "메시지를 전송했습니다: " << user_input << std::endl;
// 서버로부터의 응답 수신
ssize_t bytes_received = recv(client_socket, buffer, BUF_SIZE - 1, 0);
if (bytes_received <= 0)
{
std::cerr << "서버가 연결을 끊었거나 오류가 발생했습니다.\n";
return 1;
}
buffer[bytes_received] = '\0'; // 받은 데이터를 문자열로 변환
std::cout << "서버로부터: " << buffer << std::endl;
}
// 에러 시 while 종료
break;
}
// 클라이언트 소켓 종료
close(client_socket);
return 0;
}
'프로젝트' 카테고리의 다른 글
2024 08 02 개발일지 프로젝트 복켓몬 키우기 코드 합치기 + 버그 고치기2 (0) | 2024.08.04 |
---|---|
2024 08 01 개발일지 프로젝트 복켓몬 키우기 코드 합치기 + 버그 고치기 (0) | 2024.08.04 |
2024 07 31 개발일지 프로젝트 복켓몬 키우기 스토리 작업 및 코드 합치기 (0) | 2024.08.04 |
2024 07 30 개발일지 프로젝트 복켓몬 키우기 인터페이스 및 맵 구성 (0) | 2024.08.04 |