418
10089 ワード
1 #include <stdio.h> 2 #include <stdlib.h> //malloc() free()
3 #include <errno.h> //errno
4 #include <string.h> //strerror() strlen()
5 #include <fcntl.h> //open()
6 #include <unistd.h> //read() write() lseek() close()
7 #include <stdio_ext.h> //__fpurge
8
9 enum { MAX_INFO = 50, MAX_SUB = 8 };
10
11 typedef struct Info {
12 char id[5];
13 char name[13];
14 char sub[150];
15 } Info;
16
17 const char* Subject[MAX_SUB] =
18 { "컴퓨터개론", "이산수학", "C언어", "JAVA초급",
19 "리눅스구조", "자료구조", "컴파일러", "네트워크개론" };
20
21 void ClearStdin(char* str)
22 {
23 if (str == NULL) {
24 return;
25 }
26 if (str[strlen(str) - 1] == '\n') {
27 str[strlen(str) - 1] = '\0';
28 }
29 __fpurge(stdin);
30 }
31
32 int Enter(int* n)
33 {
34 const char enter[1] = "\n";
35 if (write(*n, enter, sizeof(enter)) < 1) {
36 fprintf(stderr, "WRITE(ENTER) errno[%d] : %s\n", errno, strerror(errno));
37 return 0;
38 }
39 return 1;
40 }
41
42 int NameCheck(char* str)
43 {
44 for (int i = 0; i < MAX_SUB; i++) {
45 if (strcmp(Subject[i], str) == 0) {
46 return 1;
47 }
48 }
49
50 printf("존재하지 않은 과목명을 입력하였습니다. 메뉴로 돌아갑니다.\n");
51 return 0;
52 }
53
54 int main()
55 {
56 Info info[MAX_INFO];
57 memset(info, '\0', MAX_INFO * sizeof(struct Info));
58
59 const char* path = "./f.txt";
60
61 int fd = 0;
62 fd = open(path, O_RDWR | O_CREAT, 0777);
63 if (-1 == fd) {
64 fprintf(stderr, "OPEN errno[%d] : %s\n", errno, strerror(errno));
65 return 0;
66 }
67
68 char buf[1000];
69 memset(buf, '\0', sizeof(buf));
70
71 int rd = 0;
72 int wr = 0;
73 rd = read(fd, info, sizeof(info));
74 //rd = read(fd, buf, sizeof(buf));
75 if (rd == -1) {
76 fprintf(stderr, "READ errno[%d] : %s\n", errno, strerror(errno));
77 close(fd);
78 return 0;
79 }
80 printf("rd: %d\n", rd);
81
82 int count = 0; //구조체 갯수 증가
83 int select = 0; //메뉴 번호 선택
84 int checkDouble; //아이디 중복확인 T/F
85 int id_int; //임시로 받는 #아이디
86 char id_char[5];
87 size_t len;
88
89 char search[13]; //출력을 위해 검색할 이름
90 memset(search, '\0', sizeof(search));
91
92 do {
93 checkDouble = 0;
94
95 /* 메뉴 선택 */
96 printf("======================\n");
97 printf("1. 수강 신청 정보 입력\n");
98 printf("2. 수강 신청 정보 출력\n");
99 printf("3. 종료\n");
100 printf("======================\n");
101 printf("select num: ");
102 scanf("%d", &select);
103 while (getchar() != '\n') {};
104 if (select != 1 && select != 2 && select != 3) {
105 printf("숫자를 다시 입력해주세요.\n");
106 }
107
108 /* 선택한 번호 */
109 switch (select) {
110 case 1:
111 {
112 /* 아이디 입력 (범위 확인하기 위해 정수형으로 받음) */
113 printf("ID: ");
114 scanf("%d", &id_int);
115 while (getchar() != '\n') {};
116 if (id_int < 1 || id_int > 1000) {
117 printf("아이디의 범위는 1부터 1000입니다. 메뉴로 돌아갑니다.\n");
118 break;
119 }
120
121 /* 문자열로 변환 후, 임시 변수에 저장함. 글자수에 맞게 공백저장 */
122 snprintf(id_char, sizeof(id_char), "%d", id_int);
123 len = strlen(id_char);
124 printf("ID 자릿수: %ld개\n", len);
125 if (len == 3) {
126 strcat(info[count].id, " ");
127 }
128 else if (len == 2) {
129 strcat(info[count].id, " ");
130 }
131 else if (len == 1) {
132 strcat(info[count].id, " ");
133 }
134 strcat(info[count].id, id_char);
135
136 /* 중복된 아이디일시, 메뉴로 돌아가고 문자열 초기화 */
137 for (int i = 0; i < count; i++) {
138 if (strcmp(info[count].id, info[i].id) == 0) {
139 printf("중복된 아이디입니다. 메뉴로 돌아갑니다.\n");
140 checkDouble = 1;
141 }
142 }
143 if (checkDouble == 1) {
144 memset(info[count].id, '\0', sizeof(info[count].id));
145 break;
146 }
147
148 /* 이름 입력 */
149 printf("이름: ");
150 fgets(info[count].name, sizeof(info[count].name), stdin);
151 ClearStdin(info[count].name);
152
153 /* 과목명 입력 (공백제거, 문자열 구분, 존재하는 과목명 체크) */
154 printf("수강 신청 과목: ");
155 fgets(info[count].sub, sizeof(info[count].sub), stdin);
156 ClearStdin(info[count].sub);
157
158 int j = 0;
159 for (size_t i = 0; i < sizeof(info[count].sub); i++) {
160 if (info[count].sub[i] != ' ') {
161 info[count].sub[j++] = info[count].sub[i];
162 }
163 }
164 info[count].sub[j] = '\0';
165
166 char copy[200];
167 strcpy(copy, info[count].sub);
168 info[count].sub[0] = '\0';
169
170 char* cut = strtok(copy, ",");
171 while (cut != NULL) {
172 if (NameCheck(cut) == 0) {
173
174 memset(info[count].id, '\0', sizeof(info[count].id));
175 memset(info[count].name, '\0', sizeof(info[count].name));
176 memset(info[count].sub, '\0', sizeof(info[count].sub));
177 break;
178 }
179 strcat(info[count].sub, cut);
180 cut = strtok(NULL, ",");
181 if (cut != NULL) {
182 strcat(info[count].sub, ", ");
183 }
184 }
185
186 count++;
187 }
188 break;
189 case 2:
190 {
191 printf("이름: ");
192 fgets(search, sizeof(search), stdin);
193 ClearStdin(search);
194
195 //lseek(fd, -4, SEEK_CUR);
196
197
198 /* const char* all = "all";
199 if (strcmp(all, search) == 0) {
200 for (int i = 0; i < count; i++) {
201
202 }
203 }
204 */
205 /* for (int i = 0; i < count; i++) {
206 if (strcmp(info[i].name, search) == 0) {
207 //id 왼쪽에 공백, name 오른쪽에 공백, all은 모두 출력, 중복이름 모두 출력
208 printf("ID: ");
209 printf("%s, ", info[i].id);
210 printf("이름: ");
211 printf("%s, ", info[i].name);
212 printf("수강신청 과목: ");
213 printf("%s\n", info[i].sub);
214 }
215 }
216 */
217
218 }
219 break;
220 case 3:
221 {
222 printf("프로그램을 종료합니다.\n");
223
224 wr = write(fd, info, sizeof(info));
225 if (wr < 1) {
226 fprintf(stderr, "WRITE error[%d] : %s\n", errno, strerror(errno));
227 close(fd);
228 return 0;
229 }
230 printf("wr: %d\n", wr);
231
232 if (-1 == close(fd)) {
233 fprintf(stderr, "CLOSE errno[%d] : %s\n", errno, strerror(errno));
234 return 0;
235 }
236 return 0;
237 }
238 break;
239 }
240 } while (select != 3);
241
242 return 0;
243 }
Reference
この問題について(418), 我々は、より多くの情報をここで見つけました https://velog.io/@doheeklm/418-zpl78vtxテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol