変更4-3


削除
#include <stdio.h>
#include <stdlib.h> //malloc() free()
#include <errno.h> //errno
#include <string.h> //strerror() strlen()
#include <fcntl.h> //open()
#include <unistd.h> //read() write() lseek() close()
#include <stdio_ext.h> //__fpurge

enum { MAX = 50, nSub = 8 };

typedef struct Info {
	int id;
	char name[13];
	char sub[150];
} Info;

const char* Subject[nSub] =
{ "컴퓨터개론", "이산수학", "C언어", "JAVA초급",
	"리눅스구조", "자료구조", "컴파일러", "네트워크개론" };

void PrintInfo(Info* info);

void ClearStdin(char* str)
{
	if (str == NULL) {
		return;
	}
	if (str[strlen(str) - 1] == '\n') {
		str[strlen(str) - 1] = '\0';
	}
	__fpurge(stdin);
}

int Enter(int* n)
{
	const char enter[1] = "\n";
	if (write(*n, enter, sizeof(enter)) < 1) {
		fprintf(stderr, "WRITE(ENTER) errno[%d] : %s\n", errno, strerror(errno));
		return 0;
	}
	return 1;
}

int NameCheck(char* str)
{
	for (int i = 0; i < nSub; i++) {
		if (strcmp(Subject[i], str) == 0) {
			return 1;
		}
	}
	printf("존재하지 않은 과목명을 입력하였습니다. 메뉴로 돌아갑니다.\n");
	return 0;
}

int main()
{
	const char* path = "./f.txt";
	int fd = 0;
	int rd = 0;
	int wr = 0;
	int infoCount = 0;
	int select = 0;
	char search[13];
	int backToMenu = 0;
	int tempID = 0;
    
	Info info;

	fd = open(path, O_RDWR | O_CREAT, 0777);
	if (fd == -1) {
		fprintf(stderr, "OPEN errno[%d] : %s\n", errno, strerror(errno));
		return 0;
	}

	memset(&info, '\0', sizeof(info));
	memset(search, '\0', sizeof(search));

	do {
		backToMenu = 0;
		infoCount = 0;
        
		printf("======================\n");
		printf("1. 수강 신청 정보 입력\n");
		printf("2. 수강 신청 정보 출력\n");
		printf("3. 종료\n");
		printf("4. 삭제\n");
		printf("======================\n");
		printf("select num: ");
		scanf("%d", &select);
		while (getchar() != '\n') {};
		if (select != 1 && select != 2 && select != 3 && select != 4) {
			printf("숫자를 다시 입력해주세요.\n");
		}
	
		switch (select) {
			case 1:
				{
					lseek(fd, (off_t)0, SEEK_SET);
					while (1) {
						rd = read(fd, &info, sizeof(info));
						if (rd == -1) {
							fprintf(stderr, "READ errno[%d] : %s\n", errno, strerror(errno));
							close(fd);
							return 0;
						}
						else if (rd == 0) {
							break;
						}
						infoCount++;
					}
					printf("Count %d\n", infoCount);
					if (infoCount >= MAX) {
						printf("최대 입력 갯수를 초과했습니다. 메뉴로 돌아갑니다.\n");
						break;
					}
					
					printf("아이디: ");
					scanf("%d", &tempID);
					while (getchar() != '\n') {};
					if (tempID < 1 || tempID > 1000) {
						printf("아이디의 범위는 1부터 1000입니다. 메뉴로 돌아갑니다.\n");
						break;
					}
				
					lseek(fd, (off_t)0, SEEK_SET);
					
					while (1) {
						rd = read(fd, &info, sizeof(info));
						if (rd == -1) {
							fprintf(stderr, "READ errno[%d] : %s\n", errno, strerror(errno));
							close(fd);
							return 0;
						}
						else if (rd == 0) {
							break;
						}
						if (tempID == info.id) {
							printf("아이디가 중복되었습니다. 메뉴로 돌아갑니다.\n");
							memset(&info, '\0', sizeof(info));
							backToMenu = 1;
							break;
						}	
					}
					if (backToMenu == 1) {
						break;
					}
					info.id = tempID;

					printf("이름: ");
					fgets(info.name, sizeof(info.name), stdin);
					ClearStdin(info.name);

					printf("수강 신청 과목: ");
					fgets(info.sub, sizeof(info.sub), stdin);
					ClearStdin(info.sub);					
					int j = 0;
					for (size_t i = 0; i < sizeof(info.sub); i++) {
						if (info.sub[i] != ' ') {
							info.sub[j++] = info.sub[i];
						}
					}
					info.sub[j] = '\0';
					char copy[200];
					strcpy(copy, info.sub);
					info.sub[0] = '\0';
					char* cut = strtok(copy, ",");
					while (cut != NULL) {
						if (NameCheck(cut) == 0) {
							memset(&info, 0, sizeof(info));
							backToMenu = 1;
							break;
						}
						strcat(info.sub, cut);
						cut = strtok(NULL, ",");
						if (cut != NULL) {
							strcat(info.sub, ", ");
						}
					}
					if (backToMenu == 1) {
						break;
					}
					
					lseek(fd, (off_t)0, SEEK_END);
					wr = write(fd, &info, sizeof(info));
					if (wr < 1) {
						fprintf(stderr, "WRITE errno[%d] : %s\n", errno, strerror(errno));
						close(fd);
						return 0;
					}
					
					memset(&info, '\0', sizeof(info));
				}
				break;
			case 2:
				{
					lseek(fd, (off_t)0, SEEK_SET);

					printf("이름 검색: ");
					fgets(search, sizeof(search), stdin);
					ClearStdin(search);
				
					while (1) {
						rd = read(fd, &info, sizeof(info));
						if (rd == -1) {
							fprintf(stderr, "READ errno[%d] : %s\n", errno, strerror(errno));
							close(fd);
							return 0;
						}
						else if (rd == 0) {
							break;
						}

						if (strcmp(search, info.name) == 0) {
							PrintInfo(&info);
						}
						else if (strcmp(search, "all") == 0) {
							PrintInfo(&info);
						}
					}
				}
				break;
			case 3:
				{
					printf("종료합니다.\n");

					if (close(fd) == -1) {
						fprintf(stderr, "CLOSE errno[%d] : %s\n", errno, strerror(errno));
						return 0;
					}
				}
				break;
			case 4:
				{
					printf("삭제할 아이디: ");
				}
				break;
		}
	} while (select != 3);

	return 0;
}

void PrintInfo(Info* info)
{
	size_t length = strlen(info->name);

	printf("ID: ");
	if (info->id < 10) {
		printf("   ");
	}
	else if (info->id < 100) {
		printf("  ");
	}
	else if (info->id < 1000) {
		printf(" ");
	}
	printf("%d, 이름: %s", info->id, info->name);
	
	if (length == 3) {
		printf("      ");
	}
	else if (length == 6) {
		printf("    ");
	}
	else if (length == 9) {
		printf("  ");
	}
	printf(", 수강신청 과목: %s\n", info->sub);
}