1/*
2 * addressbook_v1.c
3 *
4 * μ£Όμλ‘ νλ‘κ·Έλ¨ - μμ ν CRUD κΈ°λ₯ ꡬν
5 *
6 * κΈ°λ₯:
7 * 1. μ°λ½μ² μΆκ° (Create)
8 * 2. μ°λ½μ² λͺ©λ‘ 보기 (Read)
9 * 3. μ°λ½μ² κ²μ (Read)
10 * 4. μ°λ½μ² μμ (Update)
11 * 5. μ°λ½μ² μμ (Delete)
12 * 6. νμΌ μ μ₯/λΆλ¬μ€κΈ° (Persistence)
13 *
14 * μ»΄νμΌ: gcc -Wall -Wextra -std=c11 addressbook_v1.c -o addressbook
15 * μ€ν: ./addressbook
16 */
17
18#include <stdio.h>
19#include <string.h>
20#include <stdlib.h>
21
22/* μμ μ μ */
23#define MAX_CONTACTS 100
24#define NAME_LEN 50
25#define PHONE_LEN 20
26#define EMAIL_LEN 50
27#define FILENAME "contacts.dat"
28
29/* μ°λ½μ² ꡬ쑰체 */
30typedef struct {
31 int id;
32 char name[NAME_LEN];
33 char phone[PHONE_LEN];
34 char email[EMAIL_LEN];
35} Contact;
36
37/* μ£Όμλ‘ κ΅¬μ‘°μ²΄ */
38typedef struct {
39 Contact contacts[MAX_CONTACTS];
40 int count; // νμ¬ μ μ₯λ μ°λ½μ² μ
41 int next_id; // λ€μμ ν λΉν ID
42} AddressBook;
43
44/* ν¨μ μ μΈ */
45void init_addressbook(AddressBook *ab);
46void print_menu(void);
47void add_contact(AddressBook *ab);
48void list_contacts(AddressBook *ab);
49void search_contact(AddressBook *ab);
50void edit_contact(AddressBook *ab);
51void delete_contact(AddressBook *ab);
52int save_to_file(AddressBook *ab);
53int load_from_file(AddressBook *ab);
54void clear_input_buffer(void);
55int find_by_id(AddressBook *ab, int id);
56
57/* λ©μΈ ν¨μ */
58int main(void) {
59 AddressBook ab;
60 int choice;
61
62 /* μ£Όμλ‘ μ΄κΈ°ν */
63 init_addressbook(&ab);
64
65 /* νμΌμμ κΈ°μ‘΄ λ°μ΄ν° λΆλ¬μ€κΈ° */
66 if (load_from_file(&ab) == 0) {
67 printf("κΈ°μ‘΄ λ°μ΄ν°λ₯Ό λΆλ¬μμ΅λλ€. (%dλͺ
)\n", ab.count);
68 }
69
70 /* νλ‘κ·Έλ¨ μμ λ©μμ§ */
71 printf("\nβββββββββββββββββββββββββββββββββ\n");
72 printf("β π μ£Όμλ‘ νλ‘κ·Έλ¨ β\n");
73 printf("βββββββββββββββββββββββββββββββββ\n");
74
75 /* λ©μΈ 루ν */
76 while (1) {
77 print_menu();
78 printf("μ ν: ");
79
80 /* λ©λ΄ μ ν μ
λ ₯ */
81 if (scanf("%d", &choice) != 1) {
82 clear_input_buffer();
83 printf("μ«μλ₯Ό μ
λ ₯ν΄μ£ΌμΈμ.\n");
84 continue;
85 }
86 clear_input_buffer();
87
88 /* λ©λ΄ μ²λ¦¬ */
89 switch (choice) {
90 case 1:
91 add_contact(&ab);
92 break;
93 case 2:
94 list_contacts(&ab);
95 break;
96 case 3:
97 search_contact(&ab);
98 break;
99 case 4:
100 edit_contact(&ab);
101 break;
102 case 5:
103 delete_contact(&ab);
104 break;
105 case 6:
106 if (save_to_file(&ab) == 0) {
107 printf("β νμΌμ μ μ₯λμμ΅λλ€.\n");
108 }
109 break;
110 case 0:
111 /* μ’
λ£ μ μ μ₯ νμΈ */
112 printf("λ³κ²½ μ¬νμ μ μ₯νμκ² μ΅λκΉ? (y/n): ");
113 char save_confirm;
114 scanf(" %c", &save_confirm);
115 if (save_confirm == 'y' || save_confirm == 'Y') {
116 save_to_file(&ab);
117 printf("μ μ₯ μλ£.\n");
118 }
119 printf("νλ‘κ·Έλ¨μ μ’
λ£ν©λλ€.\n");
120 return 0;
121 default:
122 printf("μλͺ»λ μ νμ
λλ€.\n");
123 }
124 printf("\n");
125 }
126
127 return 0;
128}
129
130/* μ£Όμλ‘ μ΄κΈ°ν */
131void init_addressbook(AddressBook *ab) {
132 ab->count = 0;
133 ab->next_id = 1;
134 memset(ab->contacts, 0, sizeof(ab->contacts));
135}
136
137/* λ©λ΄ μΆλ ₯ */
138void print_menu(void) {
139 printf("\nβββββββββββββββββββββββββββ\n");
140 printf("β 1. μ°λ½μ² μΆκ° β\n");
141 printf("β 2. λͺ©λ‘ 보기 β\n");
142 printf("β 3. κ²μ β\n");
143 printf("β 4. μμ β\n");
144 printf("β 5. μμ β\n");
145 printf("β 6. νμΌ μ μ₯ β\n");
146 printf("β 0. μ’
λ£ β\n");
147 printf("βββββββββββββββββββββββββββ\n");
148}
149
150/* μ°λ½μ² μΆκ° */
151void add_contact(AddressBook *ab) {
152 /* μ£Όμλ‘μ΄ κ°λ μ°Όλμ§ νμΈ */
153 if (ab->count >= MAX_CONTACTS) {
154 printf("μ£Όμλ‘μ΄ κ°λ μ°Όμ΅λλ€. (μ΅λ %dλͺ
)\n", MAX_CONTACTS);
155 return;
156 }
157
158 /* μ μ°λ½μ²λ₯Ό μν ν¬μΈν° */
159 Contact *c = &ab->contacts[ab->count];
160 c->id = ab->next_id++;
161
162 printf("\nβββ μ μ°λ½μ² μΆκ° βββ\n\n");
163
164 /* μ΄λ¦ μ
λ ₯ (νμ) */
165 printf("μ΄λ¦: ");
166 fgets(c->name, NAME_LEN, stdin);
167 c->name[strcspn(c->name, "\n")] = '\0'; // κ°ν λ¬Έμ μ κ±°
168
169 if (strlen(c->name) == 0) {
170 printf("μ΄λ¦μ νμμ
λλ€. μΆκ°κ° μ·¨μλμμ΅λλ€.\n");
171 return;
172 }
173
174 /* μ νλ²νΈ μ
λ ₯ */
175 printf("μ νλ²νΈ: ");
176 fgets(c->phone, PHONE_LEN, stdin);
177 c->phone[strcspn(c->phone, "\n")] = '\0';
178
179 /* μ΄λ©μΌ μ
λ ₯ */
180 printf("μ΄λ©μΌ: ");
181 fgets(c->email, EMAIL_LEN, stdin);
182 c->email[strcspn(c->email, "\n")] = '\0';
183
184 /* μ°λ½μ² μ μ¦κ° */
185 ab->count++;
186 printf("\nβ '%s' μ°λ½μ²κ° μΆκ°λμμ΅λλ€. (ID: %d)\n", c->name, c->id);
187}
188
189/* μ°λ½μ² λͺ©λ‘ 보기 */
190void list_contacts(AddressBook *ab) {
191 printf("\nβββ μ°λ½μ² λͺ©λ‘ βββ (μ΄ %dλͺ
)\n", ab->count);
192
193 if (ab->count == 0) {
194 printf("\nμ μ₯λ μ°λ½μ²κ° μμ΅λλ€.\n");
195 return;
196 }
197
198 /* ν
μ΄λΈ ν€λ */
199 printf("\n%-4s β %-15s β %-15s β %-20s\n", "ID", "μ΄λ¦", "μ νλ²νΈ", "μ΄λ©μΌ");
200 printf("ββββββΌββββββββββββββββββΌββββββββββββββββββΌβββββββββββββββββββββ\n");
201
202 /* λͺ¨λ μ°λ½μ² μΆλ ₯ */
203 for (int i = 0; i < ab->count; i++) {
204 Contact *c = &ab->contacts[i];
205 printf("%-4d β %-15s β %-15s β %-20s\n",
206 c->id, c->name, c->phone, c->email);
207 }
208}
209
210/* μ°λ½μ² κ²μ */
211void search_contact(AddressBook *ab) {
212 char keyword[NAME_LEN];
213 int found = 0;
214
215 printf("\nβββ μ°λ½μ² κ²μ βββ\n\n");
216 printf("κ²μμ΄: ");
217 fgets(keyword, NAME_LEN, stdin);
218 keyword[strcspn(keyword, "\n")] = '\0';
219
220 if (strlen(keyword) == 0) {
221 printf("κ²μμ΄λ₯Ό μ
λ ₯ν΄μ£ΌμΈμ.\n");
222 return;
223 }
224
225 printf("\nκ²μ κ²°κ³Ό:\n");
226 printf("βββββββββββββββββββββββββββββββββββββββββββββββββββββ\n");
227
228 /* λͺ¨λ μ°λ½μ²μμ κ²μ */
229 for (int i = 0; i < ab->count; i++) {
230 Contact *c = &ab->contacts[i];
231 /* μ΄λ¦, μ νλ²νΈ, μ΄λ©μΌμμ λΆλΆ λ¬Έμμ΄ κ²μ */
232 if (strstr(c->name, keyword) != NULL ||
233 strstr(c->phone, keyword) != NULL ||
234 strstr(c->email, keyword) != NULL) {
235
236 printf("ID: %d\n", c->id);
237 printf(" μ΄λ¦: %s\n", c->name);
238 printf(" μ ν: %s\n", c->phone);
239 printf(" μ΄λ©μΌ: %s\n", c->email);
240 printf("βββββββββββββββββββββββββββββββββββββββββββββββββββββ\n");
241 found++;
242 }
243 }
244
245 if (found == 0) {
246 printf("'%s'μ λν κ²μ κ²°κ³Όκ° μμ΅λλ€.\n", keyword);
247 } else {
248 printf("μ΄ %d건 κ²μλ¨\n", found);
249 }
250}
251
252/* μ°λ½μ² μμ */
253void edit_contact(AddressBook *ab) {
254 int id;
255 char input[EMAIL_LEN];
256
257 printf("\nβββ μ°λ½μ² μμ βββ\n\n");
258 printf("μμ ν μ°λ½μ² ID: ");
259 scanf("%d", &id);
260 clear_input_buffer();
261
262 /* IDλ‘ μ°λ½μ² μ°ΎκΈ° */
263 int idx = find_by_id(ab, id);
264 if (idx == -1) {
265 printf("ν΄λΉ IDμ μ°λ½μ²λ₯Ό μ°Ύμ μ μμ΅λλ€.\n");
266 return;
267 }
268
269 Contact *c = &ab->contacts[idx];
270
271 /* νμ¬ μ 보 νμ */
272 printf("\nνμ¬ μ 보:\n");
273 printf(" μ΄λ¦: %s\n", c->name);
274 printf(" μ ν: %s\n", c->phone);
275 printf(" μ΄λ©μΌ: %s\n", c->email);
276
277 printf("\nμ μ 보λ₯Ό μ
λ ₯νμΈμ (λΉ μΉΈ: μ μ§):\n");
278
279 /* μ΄λ¦ μμ */
280 printf("μ΄λ¦ [%s]: ", c->name);
281 fgets(input, NAME_LEN, stdin);
282 input[strcspn(input, "\n")] = '\0';
283 if (strlen(input) > 0) {
284 strcpy(c->name, input);
285 }
286
287 /* μ νλ²νΈ μμ */
288 printf("μ νλ²νΈ [%s]: ", c->phone);
289 fgets(input, PHONE_LEN, stdin);
290 input[strcspn(input, "\n")] = '\0';
291 if (strlen(input) > 0) {
292 strcpy(c->phone, input);
293 }
294
295 /* μ΄λ©μΌ μμ */
296 printf("μ΄λ©μΌ [%s]: ", c->email);
297 fgets(input, EMAIL_LEN, stdin);
298 input[strcspn(input, "\n")] = '\0';
299 if (strlen(input) > 0) {
300 strcpy(c->email, input);
301 }
302
303 printf("\nβ μ°λ½μ²κ° μμ λμμ΅λλ€.\n");
304}
305
306/* μ°λ½μ² μμ */
307void delete_contact(AddressBook *ab) {
308 int id;
309
310 printf("\nβββ μ°λ½μ² μμ βββ\n\n");
311 printf("μμ ν μ°λ½μ² ID: ");
312 scanf("%d", &id);
313 clear_input_buffer();
314
315 /* IDλ‘ μ°λ½μ² μ°ΎκΈ° */
316 int idx = find_by_id(ab, id);
317 if (idx == -1) {
318 printf("ν΄λΉ IDμ μ°λ½μ²λ₯Ό μ°Ύμ μ μμ΅λλ€.\n");
319 return;
320 }
321
322 /* μμ νμΈ */
323 printf("'%s' μ°λ½μ²λ₯Ό μμ νμκ² μ΅λκΉ? (y/n): ", ab->contacts[idx].name);
324 char confirm;
325 scanf(" %c", &confirm);
326 clear_input_buffer();
327
328 if (confirm != 'y' && confirm != 'Y') {
329 printf("μμ κ° μ·¨μλμμ΅λλ€.\n");
330 return;
331 }
332
333 /* μμ : λ€μ μμλ€μ μμΌλ‘ μ΄λ */
334 for (int i = idx; i < ab->count - 1; i++) {
335 ab->contacts[i] = ab->contacts[i + 1];
336 }
337 ab->count--;
338
339 printf("β μ°λ½μ²κ° μμ λμμ΅λλ€.\n");
340}
341
342/* νμΌμ μ μ₯ (λ°μ΄λ리 λͺ¨λ) */
343int save_to_file(AddressBook *ab) {
344 FILE *fp = fopen(FILENAME, "wb");
345 if (fp == NULL) {
346 printf("νμΌ μ μ₯ μ€ν¨: νμΌμ μ΄ μ μμ΅λλ€.\n");
347 return -1;
348 }
349
350 /* λ©νλ°μ΄ν° μ μ₯ (count, next_id) */
351 fwrite(&ab->count, sizeof(int), 1, fp);
352 fwrite(&ab->next_id, sizeof(int), 1, fp);
353
354 /* μ°λ½μ² λ°°μ΄ μ μ₯ */
355 fwrite(ab->contacts, sizeof(Contact), ab->count, fp);
356
357 fclose(fp);
358 return 0;
359}
360
361/* νμΌμμ λΆλ¬μ€κΈ° (λ°μ΄λ리 λͺ¨λ) */
362int load_from_file(AddressBook *ab) {
363 FILE *fp = fopen(FILENAME, "rb");
364 if (fp == NULL) {
365 /* νμΌμ΄ μμΌλ©΄ μλ‘ μμ */
366 return -1;
367 }
368
369 /* λ©νλ°μ΄ν° μ½κΈ° */
370 fread(&ab->count, sizeof(int), 1, fp);
371 fread(&ab->next_id, sizeof(int), 1, fp);
372
373 /* μ°λ½μ² λ°°μ΄ μ½κΈ° */
374 fread(ab->contacts, sizeof(Contact), ab->count, fp);
375
376 fclose(fp);
377 return 0;
378}
379
380/* IDλ‘ μ°λ½μ² μ°ΎκΈ° (μΈλ±μ€ λ°ν) */
381int find_by_id(AddressBook *ab, int id) {
382 for (int i = 0; i < ab->count; i++) {
383 if (ab->contacts[i].id == id) {
384 return i;
385 }
386 }
387 return -1; /* μ°Ύμ§ λͺ»ν¨ */
388}
389
390/* μ
λ ₯ λ²νΌ λΉμ°κΈ° */
391void clear_input_buffer(void) {
392 int c;
393 while ((c = getchar()) != '\n' && c != EOF);
394}