[JSON을 이용한 도서 관리 프로그램]
이전에 텍스트파일 읽기를 통해 도서관리 프로그램을 만들었습니다. 이번에는 이 코드를 JSON을 이용하여 수정해주었습니다!
아래의 사이트를 참조하여 코드를 수정해주었습니다.
https://dojang.io/mod/page/view.php?id=729
C 언어 코딩 도장: 84.0 실전 예제: GitHub의 소스 코드 사용하기
이번에는 GitHub에 있는 소스 코드를 사용하여 JSON 문서를 파싱해보겠습니다. GitHub에는 수 많은 JSON 파서가 있지만 그중에서 parson을 사용해보겠습니다. 웹 브라우저에서 다음 주소에 접속하여 소
dojang.io
https://github.com/kgabis/parson
GitHub - kgabis/parson: Lightweight JSON library written in C.
Lightweight JSON library written in C. Contribute to kgabis/parson development by creating an account on GitHub.
github.com
위의 소스코드를 통해 JSON파서를 사용하였습니다.
UI는 동일하게 제작해주었습니다.
전체 도서 목록을 나열해주고, 여기서는 도서명을 변경하거나 삭제할 수 있습니다.
추천도서는 검색이 5회이상인 도서들을 출력해주었고,
검색은 작가명 혹은 도서명으로 검색이 가능합니다.
대출과 반납은 도서 목록을 불러와 대출 가능여부를 보여준 뒤 대출/반납을 할수있습니다.
먼저 헤더나 미리 정의할것들은 아래와 같습니다. UP, DOWN, ENTER 옆의 숫자는 방향키를 누르면 나오는 숫자입니다. JSON의 사용을 위해 깃허브에서 다운받은 parson.h도 추가해줍니다.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <windows.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include "parson.h"
#define UP 72
#define DOWN 80
#define ENTER 13
그리고 커서 이동을 위해 함수를 작성해줍니다. 이를통해 방향키와 엔터키를 사용하여 목록을 선택할 수 있습니다. GotoXY는 커서를 x,y위치로 옮기는것입니다.
HideCursor는 깜빡이는 커서를 안보이게 해줍니다.
void GotoXY(int x, int y) { //커서이동함수
COORD Cur = { x,y };
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), Cur);
}
void HideCursor() {
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO cursorInfo;
GetConsoleCursorInfo(hConsole, &cursorInfo); // 현재 커서 정보를 가져옴
cursorInfo.bVisible = FALSE; // 커서를 숨김
SetConsoleCursorInfo(hConsole, &cursorInfo); // 변경된 커서 정보 설정
}
그다음으로 함수 원형들을 선언해줍니다.
void Menu(); //전체 메뉴
int SelectMenu(); //메뉴 선택하기
void AddBook(JSON_Array* array, JSON_Value* rootValue); //도서 추가
void SearchBooks(JSON_Array* array, JSON_Value* rootValue); //도서 검색
void SearchAuthor(JSON_Array* array, JSON_Value* rootValue); //작가명으로 검색
void SearchBookname(JSON_Array* array, JSON_Value* rootValue); //도서명으로 검색
void Rent(JSON_Array* array, JSON_Value* rootValue); //대출/반납
void PrintBook(JSON_Array* array, JSON_Value* rootValue); // 파일에서 책 읽어오기
void RecommendBook(JSON_Array* array, JSON_Value* rootValue); //추천 도서 목록
void UpdateBook(JSON_Array* array, JSON_Value* rootValue, size_t size); //편집
메인함수는 아래와 같습니다.
int main() {
JSON_Value* rootValue = json_parse_file("Book.json"); // JSON파일을 읽어서 파싱
JSON_Object* rootObject = json_value_get_object(rootValue); // 위를 통해 object 포인터 얻기
if (rootValue == NULL) { # 파일이 비어있으면
printf("도서 목록이 비어있습니다.\n");
return 1;
}
JSON_Array* array = json_value_get_array(rootValue); // JSON의 배열들을 불러옵니다
if (array == NULL) { // 배열이 비어있다면
printf("도서 목록이 비어있습니다.\n");
json_value_free(rootValue); // 동적 메모리 해제
return 1;
}
int selectedMenu;
HideCursor();
while (1) {
selectedMenu = SelectMenu(); // 메뉴 선택
system("cls");
switch (selectedMenu) {
case 1:
PrintBook(array, rootValue); // 전체 도서 출력
break;
case 2:
RecommendBook(array, rootValue); // 추천 도서 출력
break;
case 3:
AddBook(array, rootValue); // 도서 추가
break;
case 4:
SearchBooks(array, rootValue); // 도서 검색
break;
case 5:
Rent(array, rootValue); // 대출/반납
break;
case 6:
//초기화
rootValue = json_value_init_object(); // JSON_Value 생성 및 초기화
rootObject = json_value_get_object(rootValue); // JSON_Value에서 JSON_Object를 얻음
json_serialize_to_file_pretty(rootValue, "Book.json"); // 사람이 읽기 쉬운 문자열로 만든뒤 파일에 저장
json_value_free(rootValue); // 동적 메모리 해제
array = json_value_get_array(rootValue); // 배열에 초기화된 배열 저장하기
printf("초기화 완료\n");
break;
case 7: // 종료
return 0;
}
printf("\n 엔터를 눌러 메뉴로 돌아갑니다");
getchar();
system("cls");
}
json_value_free(rootValue); // 동적 메모리 해제
return 0;
}
아래는 전체 도서를 출력해줍니다.
먼저 배열의 크기를 구해준 뒤 0이면 배열이 없는것이므로 바로 리턴해줍니다.
for문을 통해 배열의 i번째 인덱스를 통해 키가 Title인것과 Author인것의 값을 title과 author으로 저장한 뒤 출력해줍니다.
이를 화살표키를 통해 도서들에 접근하여 편집또는 삭제, 메뉴로 돌아가기를 실행할 수 있습니다.
void PrintBook(JSON_Array* array, JSON_Value* rootValue) {
size_t array_size = json_array_get_count(array);
if (array_size == 0) {
printf("Failed to get JSON array.\n");
return 1;
}
printf("========================도서 목록=========================\n");
for (size_t i = 0; i < array_size; i++) {
JSON_Object* obj = json_array_get_object(array, i);
if (obj != NULL) {
const char* title = json_object_get_string(obj, "Title");
const char* author = json_object_get_string(obj, "Author");
printf(" Title: %s, Author: %s\n", title, author);
printf("----------------------------------------------------------\n");
}
}
int getC = 1, mY = 1;
int edit = 0;
size_t size = 0;
GotoXY(1, mY);
printf("▶");
while (getC != ENTER) {
if (_kbhit()) {
getC = _getch();
switch (getC) {
case UP:
if (size > 0) {
GotoXY(1, mY);
printf(" ");
mY -= 2;
GotoXY(1, mY);
printf("▶");
size -= 2;
}
break;
case DOWN:
if (size < array_size) {
GotoXY(1, mY);
printf(" ");
mY += 2;
GotoXY(1, mY);
printf("▶");
size += 2;
}
break;
case ENTER:
system("cls");
printf("편집을 원하시면 1, 삭제를 원하시면 2, 메뉴로 돌아가기를 원하시면 3을 입력해주세요 :");
scanf("%d", &edit);
getchar();
system("cls");
if (edit == 1) {
system("cls");
UpdateBook(array, rootValue, size);
}
else if (edit == 2) {
printf("도서를 삭제합니다.\n");
//도서 삭제
json_array_remove(array, size / 2);
json_serialize_to_file_pretty(rootValue, "Book.json");
printf("도서가 삭제되었습니다!\n");
}
break;
}
}
}
}
아래는 화살표를 통해 각 메뉴들에 접근하도록 하는 코드입니다. 1보다 크면 위로 갈 수 있고,
7보다 작을때는 아래로 갈 수 있습니다. 세모를 통해 현재 커서의 위치를 알 수 있습니다.
int SelectMenu() {
Menu();
int menuSelect = 1; //메뉴 선택
int getC = 1, mY = 3;
GotoXY(6, mY);
printf("▶");
while (getC != ENTER) {
if (_kbhit()) { //키보드가 입력된 상태인가?
getC = _getch(); //누른거 아스키코드로 받음
switch (getC) {
case UP:
if (menuSelect > 1) {
GotoXY(6, mY);
printf(" ");
mY -= 2;
GotoXY(6, mY);
printf("▶");
menuSelect -= 1;
}
break;
case DOWN:
if (menuSelect < 7) {
GotoXY(6, mY);
printf(" ");
mY += 2;
GotoXY(6, mY);
printf("▶");
menuSelect += 1;
}
break;
}
}
}
return menuSelect;
}
아래는 도서를 추가해주는 코드입니다.
도서명과 작가명을 입력받아 새로운 객체를 생성하여 그곳에 값을 추가해준 뒤 배열에 새 객체를 추가해줍니다.
마지막으로는 JSON파일에 저장해줍니다.
void AddBook(JSON_Array* array, JSON_Value* rootValue) {
char title[100];
char author[100];
printf("추가할 도서 제목을 입력하세요: ");
fgets(title, sizeof(title), stdin);
title[strcspn(title, "\n")] = '\0'; // 개행 문자 제거
printf("추가할 도서 작가명을 입력하세요: ");
fgets(author, sizeof(author), stdin);
author[strcspn(author, "\n")] = '\0'; // 개행 문자 제거
// 새 객체 생성
JSON_Value* newBookValue = json_value_init_object();
JSON_Object* newBook = json_value_get_object(newBookValue);
// 새 객체에 값 추가
json_object_set_string(newBook, "Title", title);
json_object_set_string(newBook, "Author", author);
// 배열에 새 객체 추가
json_array_append_value(array, newBookValue);
// 수정된 JSON을 파일에 저장
json_serialize_to_file_pretty(rootValue, "Book.json");
printf("도서가 추가되었습니다!\n");
}
아래는 도서명이나 작가명을 편집하는 코드입니다.
선택한 도서의 인덱스를 가져와서 수정할 이름을 입력받아 값을 변경하여 JSON파일에 저장해줍니다.
void UpdateBook(JSON_Array* array, JSON_Value* rootValue, size_t size) {
size_t array_size = json_array_get_count(array);
if (array_size == 0) {
printf("수정할 도서가 없습니다.\n");
return;
}
size_t index = size / 2;
// 선택된 도서 가져오기
JSON_Object* obj = json_array_get_object(array, index);
if (obj == NULL) {
printf("도서를 가져오는 데 실패했습니다.\n");
return;
}
// 수정할 키 선택
printf("제목을 수정하고 싶으면 1, 작가명을 수정하고 싶으면 2,메뉴로 돌아가고 싶으면 3을 눌러주세요 :\n");
int choice;
scanf("%d", &choice);
getchar(); // 입력 버퍼 비우기
char newValue[100]; // 수정할 새 값
switch (choice) {
case 1:
printf("새로운 제목을 입력하세요: ");
fgets(newValue, sizeof(newValue), stdin);
newValue[strcspn(newValue, "\n")] = '\0'; // 개행 문자 제거
json_object_set_string(obj, "Title", newValue);
break;
case 2:
printf("새로운 작가명을 입력하세요: ");
fgets(newValue, sizeof(newValue), stdin);
newValue[strcspn(newValue, "\n")] = '\0'; // 개행 문자 제거
json_object_set_string(obj, "Author", newValue);
break;
case 3:
printf("수정이 취소되었습니다.\n");
return;
default:
printf("잘못된 선택입니다.\n");
return;
}
// 수정된 JSON을 파일에 저장
json_serialize_to_file_pretty(rootValue, "Book.json");
printf("도서 정보가 수정되었습니다!\n");
}
아래는 추천도서 코드입니다. 아직 나오진 않았지만 검색할때마다 Count를 증가시키도록 하였습니다. 이때의 값을 불러와서 5보다 크면 출력되도록 해주었습니다.
void RecommendBook(JSON_Array* array, JSON_Value* rootValue) {
size_t array_size = json_array_get_count(array);
if (array_size == 0) {
printf("도서 목록이 비어있습니다.\n");
return 1;
}
printf("==================== 추천 도서 목록====================\n");
for (size_t i = 0; i < array_size; i++) {
JSON_Object* obj = json_array_get_object(array, i);
if (obj != NULL) {
const char* title = json_object_get_string(obj, "Title");
const char* author = json_object_get_string(obj, "Author");
double cnt = json_object_get_number(obj, "Count");
if (cnt > 5) {
printf(" Title: %s, Author: %s\n", title, author);
printf("-------------------------------------------------------\n");
}
}
}
}
아래는 대출/반납에 관련된 코드입니다.
1을 누르면 대출, 2를 누르면 반납을 할 수 있습니다. 이때 기본 Rent 값은 0이고, 이 값이 0일때 대출이 가능합니다. 대출할때 Rent가 1이면 대출 불가능이라 표시됩니다.
Rent 값을 변경하고 바로 JSON 파일에 저장해주어야합니다.
void Rent(JSON_Array* array, JSON_Value* rootValue) {
size_t array_size = json_array_get_count(array);
if (array_size == 0) {
printf("대출/반납 가능한 도서가 없습니다.\n");
return 1;
}
int getC = 1, mY = 2;
int want = 0;
int size = 0;
printf("도서 대출을 원하시면 1, 반납을 원하시면 2를 입력해주세요 :");
scanf("%d", &want);
getchar();
if (want == 2) {
int able = 0;
printf("=======================도서 목록============================\n");
for (size_t i = 0; i < array_size; i++) {
JSON_Object* obj = json_array_get_object(array, i);
if (obj != NULL) {
const char* title = json_object_get_string(obj, "Title");
const char* author = json_object_get_string(obj, "Author");
double rent = json_object_get_number(obj, "Rent");
if (rent == 0.0f) {
printf(" Title: %s, Author: %s, 대출 가능\n", title, author);
printf("-------------------------------------------------------\n");
}
else if (rent == 1.0f) {
printf(" Title: %s, Author: %s, 대출 불가능\n", title, author);
printf("-------------------------------------------------------\n");
}
}
}
GotoXY(1, mY);
printf("▶");
while (getC != ENTER) {
if (_kbhit()) {
getC = _getch();
switch (getC) {
case UP:
if (size > 0) {
GotoXY(1, mY);
printf(" ");
mY -= 2;
GotoXY(1, mY);
printf("▶");
size -= 2;
}
break;
case DOWN:
if (size < array_size) {
GotoXY(1, mY);
printf(" ");
mY += 2;
GotoXY(1, mY);
printf("▶");
size += 2;
}
break;
case ENTER: //반납
system("cls");
JSON_Object* obj = json_array_get_object(array, size / 2);
double rent = json_object_get_number(obj, "Rent");
if (rent == 1.0f) {
rent = 0.0f;
json_object_set_number(obj, "Rent", rent);
printf("반납되었습니다! 감사합니다.\n");
array = json_value_get_array(rootValue);
json_serialize_to_file_pretty(rootValue, "Book.json");
break;
}
else {
printf("대출중인 도서가 아닙니다.\n");
break;
}
}
}
}
}
else if (want == 1) {
size_t array_size = json_array_get_count(array);
if (array_size == 0) {
printf("대출/반납 가능한 도서가 없습니다.\n");
return 1;
}
printf("=======================도서 목록============================\n");
for (size_t i = 0; i < array_size; i++) {
JSON_Object* obj = json_array_get_object(array, i);
if (obj != NULL) {
const char* title = json_object_get_string(obj, "Title");
const char* author = json_object_get_string(obj, "Author");
double rent = json_object_get_number(obj, "Rent");
if (rent == 0.0f) {
printf(" Title: %s, Author: %s, 대출 가능\n", title, author);
printf("-------------------------------------------------------\n");
}
else if (rent == 1.0f) {
printf(" Title: %s, Author: %s, 대출 불가능\n", title, author);
printf("-------------------------------------------------------\n");
}
}
}
GotoXY(1, mY);
printf("▶");
GotoXY(1, mY);
printf("▶");
while (getC != ENTER) {
if (_kbhit()) {
getC = _getch();
switch (getC) {
case UP:
if (size > 0) {
GotoXY(1, mY);
printf(" ");
mY -= 2;
GotoXY(1, mY);
printf("▶");
size -= 2;
}
break;
case DOWN:
if (size < array_size) {
GotoXY(1, mY);
printf(" ");
mY += 2;
GotoXY(1, mY);
printf("▶");
size += 2;
}
break;
case ENTER: //대출
system("cls");
JSON_Object* obj = json_array_get_object(array, size / 2);
double rent = json_object_get_number(obj, "Rent");
if (rent == 1.0f) {
printf("이미 대출중인 도서입니다.\n");
break;
}
else {
rent = 1.0f;
json_object_set_number(obj, "Rent", rent);
printf("대출되었습니다!\n");
array = json_value_get_array(rootValue);
json_serialize_to_file_pretty(rootValue, "Book.json");
break;
}
}
}
}
}
else {
printf("유효하지 않은 문자입니다.\n");
}
}
아래는 도서를 검색하는 코드입니다. 커서를 이용하여 1번부터 3번까지 접근가능합니다.
void SearchBooks(JSON_Array* array, JSON_Value* rootValue) {
printf(" 1. 작가명으로 찾기 \n");
printf(" 2. 도서명으로 찾기 \n");
printf(" 3. 메뉴로 나가기 \n");
int getC = 1, mY = 0;
int select = 1;
GotoXY(1, mY);
printf("▶");
while (getC != ENTER) {
if (_kbhit()) {
getC = _getch();
switch (getC) {
case UP:
if (select > 1) {
GotoXY(1, mY);
printf(" ");
mY -= 1;
GotoXY(1, mY);
printf("▶");
select -= 1;
}
break;
case DOWN:
if (select < 3) {
GotoXY(1, mY);
printf(" ");
mY += 1;
GotoXY(1, mY);
printf("▶");
select += 1;
}
break;
case ENTER:
switch (select) {
case 1:
SearchAuthor(array, rootValue);
break;
case 2:
SearchBookname(array, rootValue);
break;
}
}
}
}
}
아래는 작가명으로 검색하는 코드입니다.
입력받은 작가와 같은 작가가 있다면 출력해주고, Count를 증가시킨뒤 저장해줍니다.
void SearchAuthor(JSON_Array* array, JSON_Value* rootValue) {
system("cls");
size_t array_size = json_array_get_count(array);
if (array_size == 0) {
printf("Failed to get JSON array.\n");
return 1;
}
// 작가명으로 검색할 수 있는 기능 추가
char bookAuthor[100];
int found = 0;
printf("작가명을 입력해주세요 : ");
fgets(bookAuthor, sizeof(bookAuthor), stdin);
bookAuthor[strcspn(bookAuthor, "\n")] = '\0';
for (size_t i = 0; i < array_size; i++) {
JSON_Object* obj = json_array_get_object(array, i);
if (obj != NULL) {
const char* title = json_object_get_string(obj, "Title");
const char* author = json_object_get_string(obj, "Author");
double cnt = json_object_get_number(obj, "Count");
if (strcmp(author, bookAuthor) == 0) {
printf("----------------------------------------------------------\n");
printf(" Title: %s, Author: %s\n", title, author);
printf("----------------------------------------------------------\n");
cnt = cnt + 1.0f;
json_object_set_number(obj, "Count", cnt);
found = 1;
break;
}
}
}
if (!found) {
printf("찾으시는 작가님이 없습니다.\n");
}
json_serialize_to_file_pretty(rootValue, "Book.json");
}
아래는 위의 코드에서 도서명으로 바꿔주면 같습니다.
void SearchBookname(JSON_Array* array, JSON_Value* rootValue) {
system("cls");
size_t array_size = json_array_get_count(array);
if (array_size == 0) {
printf("도서 목록이 비어있습니다.\n");
return 1;
}
char bookName[100];
int able = 0;
printf("도서명을 입력해주세요 : ");
fgets(bookName, sizeof(bookName), stdin);
bookName[strcspn(bookName, "\n")] = '\0';
for (size_t i = 0; i < array_size; i++) {
JSON_Object* obj = json_array_get_object(array, i);
if (obj != NULL) {
const char* title = json_object_get_string(obj, "Title");
const char* author = json_object_get_string(obj, "Author");
double cnt = json_object_get_number(obj, "Count");
if (strcmp(title, bookName) == 0) {
printf("----------------------------------------------------------\n");
printf(" Title: %s, Author: %s\n", title, author);
printf("----------------------------------------------------------\n");
cnt = cnt + 1.0f;
printf("%lf", cnt);
json_object_set_number(obj, "Count", cnt);
able = 1;
}
}
}
if (!able) {
printf("찾으시는 도서가 없습니다.\n");
}
json_serialize_to_file_pretty(rootValue, "Book.json");
}
아래는 처음에 출력되는 메뉴입니다.
void Menu() {
printf("********************************************\n");
printf(" 도서 검색 프로그램 \n");
printf("********************************************\n");
printf(" 1 : 전체 도서 목록 \n");
printf("--------------------------------------------\n");
printf(" 2 : 추천 도서 목록 \n");
printf("--------------------------------------------\n");
printf(" 3 : 도서 추가 \n");
printf("--------------------------------------------\n");
printf(" 4 : 도서 검색 \n");
printf("--------------------------------------------\n");
printf(" 5 : 도서 대출/반납 \n");
printf("--------------------------------------------\n");
printf(" 6 : 초기화 \n");
printf("--------------------------------------------\n");
printf(" 7 : 종료 및 저장 \n");
printf("********************************************\n");
}
아래는 전체 코드입니다.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <windows.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include "parson.h"
#define UP 72
#define DOWN 80
#define ENTER 13
void GotoXY(int x, int y) { //커서이동함수
COORD Cur = { x,y };
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), Cur);
}
void HideCursor() {
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO cursorInfo;
GetConsoleCursorInfo(hConsole, &cursorInfo); // 현재 커서 정보를 가져옴
cursorInfo.bVisible = FALSE; // 커서를 숨김
SetConsoleCursorInfo(hConsole, &cursorInfo); // 변경된 커서 정보 설정
}
void Menu(); //전체 메뉴
int SelectMenu(); //메뉴 선택하기
void AddBook(JSON_Array* array, JSON_Value* rootValue); //도서 추가
void SearchBooks(JSON_Array* array, JSON_Value* rootValue); //도서 검색
void SearchAuthor(JSON_Array* array, JSON_Value* rootValue); //작가명으로 검색
void SearchBookname(JSON_Array* array, JSON_Value* rootValue); //도서명으로 검색
void Rent(JSON_Array* array, JSON_Value* rootValue); //대출/반납
void PrintBook(JSON_Array* array, JSON_Value* rootValue); // 파일에서 책 읽어오기
void RecommendBook(JSON_Array* array, JSON_Value* rootValue); //추천 도서 목록
void UpdateBook(JSON_Array* array, JSON_Value* rootValue, size_t size); //편집
int main() {
JSON_Value* rootValue = json_parse_file("Book.json");
JSON_Object* rootObject = json_value_get_object(rootValue);
if (rootValue == NULL) {
printf("도서 목록이 비어있습니다.\n");
return 1;
}
JSON_Array* array = json_value_get_array(rootValue);
if (array == NULL) {
printf("Failed to get JSON array.\n");
json_value_free(rootValue);
return 1;
}
int selectedMenu;
HideCursor();
while (1) {
selectedMenu = SelectMenu();
system("cls");
switch (selectedMenu) {
case 1:
PrintBook(array, rootValue);
break;
case 2:
RecommendBook(array, rootValue);
break;
case 3:
AddBook(array, rootValue);
break;
case 4:
SearchBooks(array, rootValue);
break;
case 5:
Rent(array, rootValue);
break;
case 6:
//초기화
rootValue = json_value_init_object(); // JSON_Value 생성 및 초기화
rootObject = json_value_get_object(rootValue); // JSON_Value에서 JSON_Object를 얻음
json_serialize_to_file_pretty(rootValue, "Book.json");
json_value_free(rootValue);
array = json_value_get_array(rootValue);
printf("초기화 완료\n");
break;
case 7:
return 0;
}
printf("\n 엔터를 눌러 메뉴로 돌아갑니다");
getchar();
system("cls");
}
json_value_free(rootValue);
return 0;
}
void PrintBook(JSON_Array* array, JSON_Value* rootValue) {
size_t array_size = json_array_get_count(array);
if (array_size == 0) {
printf("Failed to get JSON array.\n");
return 1;
}
printf("========================도서 목록=========================\n");
for (size_t i = 0; i < array_size; i++) {
JSON_Object* obj = json_array_get_object(array, i);
if (obj != NULL) {
const char* title = json_object_get_string(obj, "Title");
const char* author = json_object_get_string(obj, "Author");
printf(" Title: %s, Author: %s\n", title, author);
printf("----------------------------------------------------------\n");
}
}
int getC = 1, mY = 1;
int edit = 0;
size_t size = 0;
GotoXY(1, mY);
printf("▶");
while (getC != ENTER) {
if (_kbhit()) {
getC = _getch();
switch (getC) {
case UP:
if (size > 0) {
GotoXY(1, mY);
printf(" ");
mY -= 2;
GotoXY(1, mY);
printf("▶");
size -= 2;
}
break;
case DOWN:
if (size < array_size) {
GotoXY(1, mY);
printf(" ");
mY += 2;
GotoXY(1, mY);
printf("▶");
size += 2;
}
break;
case ENTER:
system("cls");
printf("편집을 원하시면 1, 삭제를 원하시면 2, 메뉴로 돌아가기를 원하시면 3을 입력해주세요 :");
scanf("%d", &edit);
getchar();
system("cls");
if (edit == 1) {
system("cls");
UpdateBook(array, rootValue, size);
}
else if (edit == 2) {
printf("도서를 삭제합니다.\n");
//도서 삭제
json_array_remove(array, size / 2);
json_serialize_to_file_pretty(rootValue, "Book.json");
printf("도서가 삭제되었습니다!\n");
}
break;
}
}
}
}
int SelectMenu() {
Menu();
int menuSelect = 1; //메뉴 선택
int getC = 1, mY = 3;
GotoXY(6, mY);
printf("▶");
while (getC != ENTER) {
if (_kbhit()) { //키보드가 입력된 상태인가?
getC = _getch(); //누른거 아스키코드로 받음
switch (getC) {
case UP:
if (menuSelect > 1) {
GotoXY(6, mY);
printf(" ");
mY -= 2;
GotoXY(6, mY);
printf("▶");
menuSelect -= 1;
}
break;
case DOWN:
if (menuSelect < 7) {
GotoXY(6, mY);
printf(" ");
mY += 2;
GotoXY(6, mY);
printf("▶");
menuSelect += 1;
}
break;
}
}
}
return menuSelect;
}
void AddBook(JSON_Array* array, JSON_Value* rootValue) {
char title[100];
char author[100];
printf("추가할 도서 제목을 입력하세요: ");
fgets(title, sizeof(title), stdin);
title[strcspn(title, "\n")] = '\0'; // 개행 문자 제거
printf("추가할 도서 작가명을 입력하세요: ");
fgets(author, sizeof(author), stdin);
author[strcspn(author, "\n")] = '\0'; // 개행 문자 제거
// 새 객체 생성
JSON_Value* newBookValue = json_value_init_object();
JSON_Object* newBook = json_value_get_object(newBookValue);
// 새 객체에 값 추가
json_object_set_string(newBook, "Title", title);
json_object_set_string(newBook, "Author", author);
// 배열에 새 객체 추가
json_array_append_value(array, newBookValue);
// 수정된 JSON을 파일에 저장
json_serialize_to_file_pretty(rootValue, "Book.json");
printf("도서가 추가되었습니다!\n");
}
void UpdateBook(JSON_Array* array, JSON_Value* rootValue, size_t size) {
size_t array_size = json_array_get_count(array);
if (array_size == 0) {
printf("수정할 도서가 없습니다.\n");
return;
}
size_t index = size / 2;
// 선택된 도서 가져오기
JSON_Object* obj = json_array_get_object(array, index);
if (obj == NULL) {
printf("도서를 가져오는 데 실패했습니다.\n");
return;
}
// 수정할 키 선택
printf("제목을 수정하고 싶으면 1, 작가명을 수정하고 싶으면 2,메뉴로 돌아가고 싶으면 3을 눌러주세요 :\n");
int choice;
scanf("%d", &choice);
getchar(); // 입력 버퍼 비우기
char newValue[100]; // 수정할 새 값
switch (choice) {
case 1:
printf("새로운 제목을 입력하세요: ");
fgets(newValue, sizeof(newValue), stdin);
newValue[strcspn(newValue, "\n")] = '\0'; // 개행 문자 제거
json_object_set_string(obj, "Title", newValue);
break;
case 2:
printf("새로운 작가명을 입력하세요: ");
fgets(newValue, sizeof(newValue), stdin);
newValue[strcspn(newValue, "\n")] = '\0'; // 개행 문자 제거
json_object_set_string(obj, "Author", newValue);
break;
case 3:
printf("수정이 취소되었습니다.\n");
return;
default:
printf("잘못된 선택입니다.\n");
return;
}
// 수정된 JSON을 파일에 저장
json_serialize_to_file_pretty(rootValue, "Book.json");
printf("도서 정보가 수정되었습니다!\n");
}
void RecommendBook(JSON_Array* array, JSON_Value* rootValue) {
size_t array_size = json_array_get_count(array);
if (array_size == 0) {
printf("도서 목록이 비어있습니다.\n");
return 1;
}
printf("==================== 추천 도서 목록====================\n");
for (size_t i = 0; i < array_size; i++) {
JSON_Object* obj = json_array_get_object(array, i);
if (obj != NULL) {
const char* title = json_object_get_string(obj, "Title");
const char* author = json_object_get_string(obj, "Author");
double cnt = json_object_get_number(obj, "Count");
if (cnt > 5) {
printf(" Title: %s, Author: %s\n", title, author);
printf("-------------------------------------------------------\n");
}
}
}
}
void Rent(JSON_Array* array, JSON_Value* rootValue) {
size_t array_size = json_array_get_count(array);
if (array_size == 0) {
printf("대출/반납 가능한 도서가 없습니다.\n");
return 1;
}
int getC = 1, mY = 2;
int want = 0;
int size = 0;
printf("도서 대출을 원하시면 1, 반납을 원하시면 2를 입력해주세요 :");
scanf("%d", &want);
getchar();
if (want == 2) {
int able = 0;
printf("=======================도서 목록============================\n");
for (size_t i = 0; i < array_size; i++) {
JSON_Object* obj = json_array_get_object(array, i);
if (obj != NULL) {
const char* title = json_object_get_string(obj, "Title");
const char* author = json_object_get_string(obj, "Author");
double rent = json_object_get_number(obj, "Rent");
if (rent == 0.0f) {
printf(" Title: %s, Author: %s, 대출 가능\n", title, author);
printf("-------------------------------------------------------\n");
}
else if (rent == 1.0f) {
printf(" Title: %s, Author: %s, 대출 불가능\n", title, author);
printf("-------------------------------------------------------\n");
}
}
}
GotoXY(1, mY);
printf("▶");
while (getC != ENTER) {
if (_kbhit()) {
getC = _getch();
switch (getC) {
case UP:
if (size > 0) {
GotoXY(1, mY);
printf(" ");
mY -= 2;
GotoXY(1, mY);
printf("▶");
size -= 2;
}
break;
case DOWN:
if (size < array_size) {
GotoXY(1, mY);
printf(" ");
mY += 2;
GotoXY(1, mY);
printf("▶");
size += 2;
}
break;
case ENTER: //반납
system("cls");
JSON_Object* obj = json_array_get_object(array, size / 2);
double rent = json_object_get_number(obj, "Rent");
if (rent == 1.0f) {
rent = 0.0f;
json_object_set_number(obj, "Rent", rent);
printf("반납되었습니다! 감사합니다.\n");
array = json_value_get_array(rootValue);
json_serialize_to_file_pretty(rootValue, "Book.json");
break;
}
else {
printf("대출중인 도서가 아닙니다.\n");
break;
}
}
}
}
}
else if (want == 1 || want == 2) {
size_t array_size = json_array_get_count(array);
if (array_size == 0) {
printf("대출/반납 가능한 도서가 없습니다.\n");
return 1;
}
printf("=======================도서 목록============================\n");
for (size_t i = 0; i < array_size; i++) {
JSON_Object* obj = json_array_get_object(array, i);
if (obj != NULL) {
const char* title = json_object_get_string(obj, "Title");
const char* author = json_object_get_string(obj, "Author");
double rent = json_object_get_number(obj, "Rent");
if (rent == 0.0f) {
printf(" Title: %s, Author: %s, 대출 가능\n", title, author);
printf("-------------------------------------------------------\n");
}
else if (rent == 1.0f) {
printf(" Title: %s, Author: %s, 대출 불가능\n", title, author);
printf("-------------------------------------------------------\n");
}
}
}
GotoXY(1, mY);
printf("▶");
GotoXY(1, mY);
printf("▶");
while (getC != ENTER) {
if (_kbhit()) {
getC = _getch();
switch (getC) {
case UP:
if (size > 0) {
GotoXY(1, mY);
printf(" ");
mY -= 2;
GotoXY(1, mY);
printf("▶");
size -= 2;
}
break;
case DOWN:
if (size < array_size) {
GotoXY(1, mY);
printf(" ");
mY += 2;
GotoXY(1, mY);
printf("▶");
size += 2;
}
break;
case ENTER: //대출
system("cls");
JSON_Object* obj = json_array_get_object(array, size / 2);
double rent = json_object_get_number(obj, "Rent");
if (rent == 1.0f) {
printf("이미 대출중인 도서입니다.\n");
break;
}
else {
rent = 1.0f;
json_object_set_number(obj, "Rent", rent);
printf("대출되었습니다!\n");
array = json_value_get_array(rootValue);
json_serialize_to_file_pretty(rootValue, "Book.json");
break;
}
}
}
}
}
else {
printf("유효하지 않은 문자입니다.\n");
}
}
void SearchBooks(JSON_Array* array, JSON_Value* rootValue) {
printf(" 1. 작가명으로 찾기 \n");
printf(" 2. 도서명으로 찾기 \n");
printf(" 3. 메뉴로 나가기 \n");
int getC = 1, mY = 0;
int select = 1;
GotoXY(1, mY);
printf("▶");
while (getC != ENTER) {
if (_kbhit()) {
getC = _getch();
switch (getC) {
case UP:
if (select > 1) {
GotoXY(1, mY);
printf(" ");
mY -= 1;
GotoXY(1, mY);
printf("▶");
select -= 1;
}
break;
case DOWN:
if (select < 3) {
GotoXY(1, mY);
printf(" ");
mY += 1;
GotoXY(1, mY);
printf("▶");
select += 1;
}
break;
case ENTER:
switch (select) {
case 1:
SearchAuthor(array, rootValue);
break;
case 2:
SearchBookname(array, rootValue);
break;
}
}
}
}
}
void SearchAuthor(JSON_Array* array, JSON_Value* rootValue) {
system("cls");
size_t array_size = json_array_get_count(array);
if (array_size == 0) {
printf("Failed to get JSON array.\n");
return 1;
}
// 작가명으로 검색할 수 있는 기능 추가
char bookAuthor[100];
int found = 0;
printf("작가명을 입력해주세요 : ");
fgets(bookAuthor, sizeof(bookAuthor), stdin);
bookAuthor[strcspn(bookAuthor, "\n")] = '\0';
for (size_t i = 0; i < array_size; i++) {
JSON_Object* obj = json_array_get_object(array, i);
if (obj != NULL) {
const char* title = json_object_get_string(obj, "Title");
const char* author = json_object_get_string(obj, "Author");
double cnt = json_object_get_number(obj, "Count");
if (strcmp(author, bookAuthor) == 0) {
printf("----------------------------------------------------------\n");
printf(" Title: %s, Author: %s\n", title, author);
printf("----------------------------------------------------------\n");
cnt = cnt + 1.0f;
json_object_set_number(obj, "Count", cnt);
found = 1;
break;
}
}
}
if (!found) {
printf("찾으시는 작가님이 없습니다.\n");
}
json_serialize_to_file_pretty(rootValue, "Book.json");
}
void SearchBookname(JSON_Array* array, JSON_Value* rootValue) {
system("cls");
size_t array_size = json_array_get_count(array);
if (array_size == 0) {
printf("도서 목록이 비어있습니다.\n");
return 1;
}
char bookName[100];
int able = 0;
printf("도서명을 입력해주세요 : ");
fgets(bookName, sizeof(bookName), stdin);
bookName[strcspn(bookName, "\n")] = '\0';
for (size_t i = 0; i < array_size; i++) {
JSON_Object* obj = json_array_get_object(array, i);
if (obj != NULL) {
const char* title = json_object_get_string(obj, "Title");
const char* author = json_object_get_string(obj, "Author");
double cnt = json_object_get_number(obj, "Count");
if (strcmp(title, bookName) == 0) {
printf("----------------------------------------------------------\n");
printf(" Title: %s, Author: %s\n", title, author);
printf("----------------------------------------------------------\n");
cnt = cnt + 1.0f;
printf("%lf", cnt);
json_object_set_number(obj, "Count", cnt);
able = 1;
}
}
}
if (!able) {
printf("찾으시는 도서가 없습니다.\n");
}
json_serialize_to_file_pretty(rootValue, "Book.json");
}
void Menu() {
printf("********************************************\n");
printf(" 도서 검색 프로그램 \n");
printf("********************************************\n");
printf(" 1 : 전체 도서 목록 \n");
printf("--------------------------------------------\n");
printf(" 2 : 추천 도서 목록 \n");
printf("--------------------------------------------\n");
printf(" 3 : 도서 추가 \n");
printf("--------------------------------------------\n");
printf(" 4 : 도서 검색 \n");
printf("--------------------------------------------\n");
printf(" 5 : 도서 대출/반납 \n");
printf("--------------------------------------------\n");
printf(" 6 : 초기화 \n");
printf("--------------------------------------------\n");
printf(" 7 : 종료 및 저장 \n");
printf("********************************************\n");
}