1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include<stdio.h>
 
int main()
{
    unsigned char  uc = -8;
    signed char sc=-8;
    
    printf("unsigned char : %d\n" , uc);    //248
    printf("signed char : %d\n",sc);        //-8
    
    unsigned int  iuc = -1;
    signed int isc=-1;
    
    printf("unsigned int : %d\n" , iuc);    //-1
    printf("signed int : %d\n",isc);        //-1
 
    short ss = 0x8c;
    signed char sc = 0x8c;
    
    printf("%d\n",(int)ss);                    //140
    printf("%x",(int)sc);                    //ffffff8c
    return 0;  
}
cs



 

 unsigned char

signed char

 범위

0~255 

-128~127 

공통점

1byte로 2진수로 표현하면

1000 1000 ->(부호 비트 제외한 2의 보수) 1111 1000

차이점 

부호 비트가 없으므로

248

(128+64+32+16+8)

 첫 번째 비트는 부호 비트로 

1은 음수이므로

-8

(-128+64+32+16+8)


*char 타입은 다른 타입들과 달리 signed/unsigned가 명시되어 있지 않습니다.

그래서 가급적이면 명시를 해서 사용하는 것이 좋습니다.



 

 unsigned int

signed int 

 범위

 0~4294967295

-2147483648~2147483647 

공통점 

4byte로 2진수로 표현하면

1000 0000 0000 0000 0000 0000 0000 00001 

(부호 비트 제외한 2의보수)

1111 1111 1111 1111 1111 1111 1111 1111


*출력 포맷 형식인 %d는 기본적으로 signed int형으로 명시 되어있습니다.

그래서 unsigned int에서 -1을 넣어도 첫 번째 비트를 부호 비트로 인식하여 signed int과 같은 방식으로 처리되어 결과값이 -1이 나옵니다.




*정수의 승격(Integral Promotion)

short ss = 0x8c; 는 0000 0000 1000 1100 입니다.


(int)ss 하면 정수 승격이 발생하여 0000 0000 0000 0000 0000 0000 1000 1100 이 된다.

(이때, short는 2byte이므로 나머지 2byte는 최상위비트로 공간을 채웁니다.)


%d 이고 양수이므로 바로 출력하면 140 이 됩니다.


char sc = 0x8c; 는 1000 1100 입니다.

(int)sc 하면 정수 승격이 발생하여 1111 1111 1111 1111 1111 1111 1000 1100 이 된다.

(이때, char 는 1byte이므로 나머지 2byte는 최상위비트로 공간을 채웁니다.)


%x 이므로 16 진수이므로 바로 출력하면 ffff ff8c 이 된다.


==>될수 있으면 int형을 사용하는 것이 성능면에서 효율적입니다.










Bus.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include<stdio.h>
#include <stdlib.h>
#include<string.h> 
#include<time.h>  
 
typedef struct bus
{
    int num; // 회원 번호
    char name[15]; //이름 
}BUS;
 
typedef struct price
{
    int num;
    char pwd[11];
    time_t B_time; // 예약 시간
    time_t O_time; // 예약 취소 시간
    char Name[15]; // 이름
    int Seat; // 자리 
    int flag; // 1:성인 2:아동 
}PRICE;
 
int e_cnt=0;//회원 등록 인원 수 
int seat_cnt=0;//버스 자리 수 
int total;//총 정산 요금 
 
int disp_menu(void);
void Bus_Format(BUS* (*Bus)[4]);    //Bus 초기화 
void Price_Format(PRICE* *Price);    //Price 초기화 
void AllFree(BUS* (*Bus)[4], PRICE* *Price); //free
 
void Bus_print(BUS* (*Bus)[4]);//버스 좌석 print 
void Bus_Book(BUS* (*Bus)[4], PRICE* *Price,int* login_num,int *e_num, char (*e_pwd)[11]);//버스 좌석 예약 
void Bus_BookCancle(BUS* (*Bus)[4], PRICE* *Price); // 버스 좌석 예약 취소
int is_Bus_Book(BUS* (*Bus)[4],int row,int col);//좌석이 남아있는지 check 
void Add_Price(BUS* (*Bus)[4], PRICE* *Price, char* Name, int Seat,int num,char* pwd, int flag); //정산 기록 저장 
void Price_Print(PRICE* *Price); // 정산 기록 출력
void Bus_BookList(PRICE* *Price,int *login_num);//티켓 조회 
void Save(BUS* (*Bus)[4], PRICE* *Price); // 정산 기록 save 
 
void enroll_num(int *e_num, char (*e_pwd)[11], int login_num);    //회원가입 
int is_enroll_num(int num, int *e_num);    //회원번호 검사 
void insertID(int id, int *e_num, char (*e_pwd)[11]);    //회원 저장 
void input_password(char *pwd);    //비밀번호 저장 
void insertToIDList(int id, char* pwd, int *e_num, char (*e_pwd)[11]); //회원 저장 
void printIDList(int *e_num, char (*e_pwd)[11]);
 
void login_out(int *e_num, char (*e_pwd)[11], int *login_num);    //login/out
 
int Price_sum(int (*fp)(int));    //정산 요금 추가 
int adult_add(int sum);
int adult_sub(int sum);
int child_add(int sum);
int child_sub(int sum);
cs

Bus.c


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
#include "Bus.h"
 
 
void Bus_Format(BUS* (*Bus)[4]) // 버스 좌석 NULL로 초기화 
{
    int i, j;
    
    for(i=0; i<20; i++)
    {
        for(j=0; j<4; j++)
        {
            Bus[i][j] = NULL;
            
        }
    }
}
 
void Price_Format(PRICE* *Price) // 요금 정산 기록 NULL로 초기화 
{
    int i;
    
    for(i=0; i<120; i++)
    {
        Price[i] = NULL;    
    }
}
 
void AllFree(BUS* (*Bus)[4], PRICE* *Price)//동적 할당 해제 
{
    int i, j;
    
    if(Price[0== NULL)
    {
        return;
    }
    
    for(i=0; i<20; i++)
    {
        for(j=0; j<4; j++)
        {
            if(Bus[i][j] != NULL)
            {
                free(Bus[i][j]);
            }
        }
    }
    
    for(i=0; i<120; i++)
    {
        if(Price[i] == NULL)
        {
            break;
        }
        free(Price[i]);
    }
 
}
 
int main()
{
    int num;
    int login_num = 0;
    BUS* Bus[20][4];
    PRICE* Price[120];
    Bus_Format(Bus); 
    Price_Format(Price); 
    int e_num[10]={0};           
    char e_pwd[10][11]={""}; 
    
    while (1)
    {
        num = disp_menu();
 
 
        switch (num)
        {
        case 1
        enroll_num(e_num, e_pwd,login_num); break;
        case 2
        login_out(e_num, e_pwd, &login_num); break;
        case 3:
        Bus_Book(Bus,Price,&login_num,e_num,e_pwd); break;
        case 4:
        Bus_BookList(Price,&login_num); break;
        case 5:
        Bus_BookCancle(Bus,Price); break;
        case 6:
        Price_Print(Price); break;
        case 7
        Save(Bus,Price); break;
        case 0:
        AllFree(Bus,Price); return;
        default:
            printf("@ 메뉴 번호가 아닙니다!\n\n");
            break;
        }
    }
    return 0;
}
 
int disp_menu()
{
    int num;
 
    printf("\n===[ 버스 예약 시스템 ]===\n");
    printf("1. 회원가입\n");
    printf("2. 로그인/로그아웃\n");
    printf("3. 버스 예약 \n");           
     printf("4. 티켓 조회\n");         
     printf("5. 예약 취소\n");
    printf("6. 티켓 정산\n");
    printf("7. Save\n");
    printf("0. 종료\n");
    printf("--------------------------\n");
 
    printf("> 번호 선택 : ");
    scanf("%d"&num);
 
    return num;
}
void Bus_print(BUS* (*Bus)[4])
{
 
    int i,j;
    int seat=0, nonseat=0;
 
    
    printf("=========버스좌석========\n");
    
    for(i=0;i<20;i++)
    {
        for(j=0;j<4;j++)
        {
            if(Bus[i][j] == NULL)
            {
                printf("□ ");
                seat++;
            }
            else
            {
                printf("■ ");
                nonseat ++;
            }
        }
        printf(" (%d ~ %d)",(i*4)+1,(i*4)+4);
        printf("\n");
    }
        printf("\n[빈자리 □] [자리 없음 ■]\n");
        printf("예약 가능 자리: %d개  예약된 자리: %d개\n\n", seat, nonseat);
        fflush(stdin);
}
 
void Bus_Book(BUS* (*Bus)[4], PRICE* *Price,int* login_num,int *e_num, char (*e_pwd)[11])
{
        int num ,seat,i,flag;
        int row,col;
        char yn;
        char Name[10];
        char pwd[11]="";
        int index;
        
        if (*login_num == 0)                  
        {
            printf("@ 로그인후 사용가능합니다!\n");
            return;
        }
            
        Bus_print(Bus);
        
            printf("# 이름을 입력하세요 : ");
            scanf("%s", Name);
            
            fflush(stdin);
 
            printf("# 자리를 입력하세요 : "); 
            scanf("%d",&seat);
                
            fflush(stdin);
            
        row = seat/4;
        col = seat%4-1;
        
        //버스 자리 있는지 검사 
        if(is_Bus_Book(Bus, row, col))
        {        
            return ;
        }
        
        //현재 로그인된 회원의 비밀번호 저장 
        for(i=0;i<e_cnt;i++)
            {
            if(*login_num==e_num[i])
                {
                        index=i;
                        break;    
                }
            }
        strcpy(pwd,e_pwd[index]);
        
        
        printf("@ 1 : 성인 요금은 20000원 입니다. \n");
        printf("@ 2 : 아동 요금은 10000원 입니다. \n");
        printf("> 입력 : "); 
        scanf("%d",&flag);
        fflush(stdin);
        
        printf("\n# 예약 하시겠습니까?(y/ n): ");
        
        scanf("%c"&yn); 
        if(yn == 'y')
            {
                Bus[row][col] = (BUS*)malloc(sizeof(BUS));
                strcpy(Bus[row][col]->name, Name);
                num = *login_num;    
                Bus[row][col]->num=num;
                Add_Price(Bus, Price, Name, seat,num,pwd,flag);
                seat_cnt++;
                printf("@ 예약 되었습니다\n");
            }
        else
            {
                printf("@ 취소 되었습니다\n"); 
            }    
            
        
    
    
 
int is_Bus_Book(BUS* (*Bus)[4], int row,int col)
{
        if(Bus[row][col] == NULL)
    {
        return 0;
    }
    else
    {
        printf("\n@ 자리가 없습니다.");
        return 1;    
    }
    
}
void Add_Price(BUS* (*Bus)[4], PRICE* *Price, char* Name, int Seat,int num,char* pwd,int flag)
{
    int i;
    time_t B_time;
    
    B_time = time(NULL);
         
    for(i=0; i<120; i++)
    {
        if(Price[i] == NULL)
        {
            Price[i] = (PRICE*)calloc(80,sizeof(PRICE));
            strcpy(Price[i]->Name, Name);
            Price[i]->Seat = Seat;
            Price[i]->num = num;
            Price[i]->flag=flag;
            strcpy(Price[i]->pwd,pwd);
            Price[i]->B_time = time(&B_time);    // 예약 시간 저장
            break;
        }
    }
 
}
 
void Bus_BookList(PRICE* *Price,int* login_num)
{    
    int i,count=0;
    
    if (*login_num == 0)                  
    {
        printf("@ 로그인후 사용가능합니다!\n");
        return;
    }
    
    printf("\n<==========티켓 조회==========>\n"); 
    for(i=0; i<120; i++)
    {     
            if(Price[i] == NULL)
            {
                break ;
            }
            else if(Price[i]->num==*login_num)        //로그인된 회원만 조회 
            {            
            printf("# 예약자 이름: %s\n" ,Price[i]->Name);                             
            printf("# 예약 좌석 : %d\n", Price[i]->Seat);
            if(strcmp(ctime(&Price[i]->O_time),"Thu Jan 01 09:00:00 1970\n"))
            {
                printf("<<<취소된 티켓입니다.>>>\n");
            }
            printf("================================\n");
            count++;
            }        
    }
 
    if(!count)
    printf("@ 예약된 티켓이 없습니다.\n");
}
 
void Bus_BookCancle(BUS* (*Bus)[4], PRICE* *Price)
{
    char pwd[11= "";
    int seat,i; 
    int row,col; 
    time_t O_time;
    
    O_time = time(NULL);
    
    printf("# 좌석을 입력하세요 : "); 
    scanf("%d",&seat);
    
 
    row = seat/4;
    col = seat%4-1;
 
 
 
    for(i=0; i<120; i++)
        {     
            if(Price[i] == NULL)
            {
                printf("@ 티켓 목록이 없습니다!\n"); 
                break;
            }
            else if(Price[i]->Seat==seat)
            {            
                printf("# 비밀번호를 입력하세요 : ");
                scanf("%s",pwd);
                
                if(!strcmp(pwd,Price[i]->pwd))
                {
                    Price[i]->O_time=O_time;//예약 취소 시간 저장 
                    Bus[row][col]=NULL;
                    printf("@ 예약이 취소되었습니다.\n"); 
                    break;
                }
                else
                {
                    printf("@ 비밀번호가 틀렸습니다\n");
                    break
                }
            }
        }
}
 
void Price_Print(PRICE* *Price)
{
    int i;
    int sum = 0;
        
    for(i=0; i<120; i++)
    {
        if(Price[i] == NULL)
        {
            break;
        }
                
        if(Price[i]->Name != NULL// 예약자가 있을때만 출력 
        {
            printf("\n예약자 이름: %s\n", Price[i]->Name);
        }
        
        printf("예약 자리: %d\n", Price[i]->Seat);
                
        printf("예약 형태: 좌석");
        if(Price[i]->flag==1)
        {
            sum += Price_sum(adult_add);
            printf("[성인] \n");
        }
        if(Price[i]->flag==2)
        {
            sum += Price_sum(child_add);
            printf("[아동] \n");    
        }
        
        printf("예약 시간: %s\n", ctime(&Price[i]->B_time));
        
        if(strcmp(ctime(&Price[i]->O_time),"Thu Jan 01 09:00:00 1970\n"))
        {
            printf("취소 시간: %s\n", ctime(&Price[i]->O_time));
            if(Price[i]->flag==1)
            sum +=Price_sum(adult_sub);    
            if(Price[i]->flag==2)
            sum +=Price_sum(child_sub);        
        }
 
    }
    
    printf("\n정산 요금: %d\n", sum);
    total = sum;
}
 
void Save(BUS* (*Bus)[4], PRICE* *Price)
{
    FILE *fp = fopen("Bus.txt""w");   
    char yn;
    char str[10];
    int i;
    
    if(Price[0== NULL)
    {
        return;
    }
 
    fflush(stdin);
    
    printf("\n세이브 하시겠습니까?(y / n): ");
    scanf("%c"&yn);
    
    
    if(yn == 'y')
    {
        for(i=0;i<seat_cnt;i++)     // 파일에 문자열 저장
        {
            fputs("예약자 이름 :", fp);
             fputs(Price[i]->Name, fp); 
             fputs("\n", fp);
            fputs("예약시간 :", fp);
            fputs(ctime(&Price[i]->B_time), fp);
            fputs("취소시간 :", fp);
            if(!strcmp(ctime(&Price[i]->O_time),"Thu Jan 01 09:00:00 1970\n"))
            {
                fputs("\n", fp);
            }
            else
                fputs(ctime(&Price[i]->O_time), fp);
    
            fputs("좌석 :",fp); 
            itoa(Price[i]->Seat,str,10);
            fputs(str, fp);
            if(Price[i]->flag==1)
            fputs("[성인] \n",fp);
            if(Price[i]->flag==2)
            fputs("[아동] \n",fp);    
            
            
        }
    }
    fputs("\n정산 요금 : ",fp);    
    itoa(total,str,10);
    fputs(str,fp);    
    
    fclose(fp);   
}
 
void enroll_num(int *e_num, char (*e_pwd)[11], int login_num)
{
    int num;                                      
    int index;                                  
 
    if (login_num != 0)                   
    {
        printf("@ 로그아웃 후 사용할 수 있습니다!\n");
        return;
    }
 
    printf("\n======[ 회원 가입 ]======\n\n");
    
    printf("# 회원번호를 입력하세요 :");
    scanf("%d",&num); 
    
    
    index = is_enroll_num(num,e_num);     // 등록이 되어 있는지 확인
 
    if (index >= 0)                           
    {
        printf("@ 이미 회원가입된 번호입니다\n"); 
    }
    else                                              // 처음 등록하는 경우
    {
        insertID(num, e_num, e_pwd);
    }
}
 
int is_enroll_num(int num, int *e_num)
{
    int i;
 
    for (i = 0; i < e_cnt; i++)
    {
        if (num == e_num[i]) return i;
    }
    return -1;
}
 
void insertID(int id, int *e_num, char (*e_pwd)[11]){
    char pwd[11= "";
    
    input_password(pwd);    
    insertToIDList(id, pwd, e_num, e_pwd);
    printIDList(e_num, e_pwd);
}
 
void input_password(char *pwd)
{
    char first[11];      
    char second[11]; 
    int flag=0;
 
    do {
        while (1)
        {
            printf("> 비밀번호 : ");
            scanf("%s",first);
            if(strlen(first)>10)
            {
                printf("@ 비밀번호가 너무 깁니다  \n");
                flag=1;
            }
            else
            {
                flag=0;
            }
            if (flag==0break;
 
        }
 
        printf("> 한번 더 입력하세요. : ");
        scanf("%s",second);
        if ( strcmp(first, second) == 0)   break;
 
        printf("@ 비밀번호가 일치하지 않습니다!\n");
    } while (1);
    
    strcpy(pwd,first);
}
 
void insertToIDList(int id, char* pwd, int *e_num, char (*e_pwd)[11]) {
    e_num[e_cnt] = id;
    strcpy(e_pwd[e_cnt], pwd);
    e_cnt++;                                  
    printf("@ %d번이 등록되었습니다!\n", id);
}
 
void printIDList(int *e_num, char (*e_pwd)[11]){
    int i=0;
 
    printf("\n>> 현재 등록된 회원번호(비밀번호) : ");
    for (i = 0; i < e_cnt; i++)
    {
        printf("%5d(%s)", e_num[i], e_pwd[i]);
    }
    printf("\n\n");
}
 
void login_out(int *e_num, char (*e_pwd)[11], int *login_num)
{
    int num;
    char pwd[11]="";
    int index;
 
    if (*login_num != 0)
    {
        *login_num = 0;
        printf("# 로그아웃 되었습니다!\n");
        return;
    }
 
    printf("\n[ 로그인 ]\n\n");
 
    printf("> 회원번호 : ");
    scanf("%d"&num);
    index = is_enroll_num(num, e_num);
 
    if (index == -1)
    {
        printf("@ %d번은 등록되지 않은 번호입니다!\n", num);
        return;
    }
 
    printf("> 비밀번호 : ");
    fflush(stdin); gets(pwd);
    if (strcmp(pwd, e_pwd[index]) != 0)
    {
        printf("@ 비밀번호가 틀렸습니다!\n");
        return;
    }
    *login_num = num;               
    printf("@ 로그인 되었습니다!\n");
    
}
int Price_sum(int (*fp)(int))
{
    int sum=0;
    return fp(sum);
}
int adult_add(int sum)
{
    
    return sum+20000;    
}
int adult_sub(int sum)
{
    
    return sum-20000;    
}
int child_add(int sum)
{
    
    return sum+10000;    
}
int child_sub(int sum)
{
    
    return sum-10000;    
}
cs



■ 파일 입출력 ■


*fopen으로 열고 flose로 닫는다.


개방 모드 

 파일이 있을 때

 파일이 없을 때

 r

읽기만 

null 반환 

 w

내용 지우고 쓰기 

새로운 파일 자동 생성 

 a

내용 이어 쓰기 

새로운 파일 자동 생성 


1. fopen -> 메모리에 stream file 생성

*stream file은 문자 배열 형태의 버퍼를 가지고 있다.


버퍼에서 데이터를 읽거나 쓸 때 필요한 정보들을 구조체로 묶어서 보관합니다.

(=> 파일의 데이터 양을 버퍼만으로 관리할 수 없어서)

그래서 파일 포인터(파일 구조체 주소)를 반환합니다.



#문자 입력 함수 fgetc : 파일에서 문자 입력(파일에서 데이터를 읽어옴)

#문자 출력 함수 fputc : 문자를 파일에 출력(파일에 데이터 저장)



텍스트 파일

 바이너리 파일

 r, w, a

 rb, wb, ab

 +를 붙이면 읽고 쓰기 작업이 동시에 가능

(r+, w+, a+, rb+, wb+, ab+)


*텍스트 파일은 아스키 코드값에 따라 데이터를 읽고 

그외의 파일 형식을 바이너리 파일이라고 알고 있으면 된다.

(바이너리 파일 같은 파일은 메모장으로 열면 안보이고 Notepad++같은 tool을 이용해서 볼 수 있다) 



#문자 입력 함수 fgets 

#문자 출력 함수 fputs 

*문자열을 읽을 때 주의 할 점 : 문자열의 마지막 앞에 (NULL 앞에) \n(개행문자)가 존재한다는 것을 인식하자


예)        .txt

abc

def

123


1. 첫 줄 읽어 오기

2. str[strlen(str) -1] = '\0';    //개행문자를 대신하면 \0을 넣어줘서 개행문자 제거



#입력 함수 fscanf 

#출력 함수 fprintf


->흔히 쓰는 scanf, printf를 파일을 지정하여 쓸 수 있다 => 보편적으로 많이 이용한다.


/*형식 예

FILE *fp;

int res = fscanf(fp, "%s%d",name,&data);

*/


#파일을 읽기 전용 으로 읽을 때 파일이 있는지 예외처리를 해주자

<예>

FILE *fp;

if(fp ==NULL)

{

return 1;

}



#파일의 내용이 있는지 검는지 검사 형식


*파일을 다 읽으면 EOF를 반환한다.

*입력시 Ctrl + z를 누르면 EOF(-1)를 반환 한다.

1.

if(res ==EOF)//

{

break;

}


2.

if(feof(fp))

{

break;

}



#매출 관리 프로그램

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#include<stdio.h>
#include<string.h>
#include <stdlib.h>
typedef struct
{
    char title[30];   
    double price;     
    int count;          
    double tot;    
     
} Book;
 
int check(char *title, Book *book, int count);
 
int main()
{
    FILE *ifp,*ofp;
    Book book[10];
    char title[30]; 
    double price;     
    int count,i=0,num,k;  
    int j;
    int max; 
    
    ifp = fopen("a.txt","r");
    if(ifp == NULL)
    {
        printf("a.txt 열지 못했습니다.\n");
        return 1;
    }
    
    ofp = fopen("b.txt""w");
    if (ofp == NULL)
    {
        printf("b.txt 열지 못했습니다.\n");
        return 1;
    }
    
    fgets(title,sizeof(title),ifp);
    
    while(!feof(ifp))
    {
 
        title[strlen(title)-1= '\0';
        fscanf(ifp,"%lf%d",&price,&count);
        fgetc(ifp);
        num = check(title, book,i);
        
        if(num>=0)
            {
                book[num].tot +=(price * count);
            }
        else
            {
            strcpy(book[i].title,title);
            book[i].price=price;
            book[i].count = count;
            book[i].tot = price * count;
            i++;
            }
            
        fgets(title,sizeof(title),ifp);    
    }
 
    
    //정렬
    k=i;
 
    for(i=0;i<k-1;i++)
    {
        max = i;
        for(j=i+1;j<k;j++)
        {
            if(book[j].tot > book[max].tot)
            max = j;    
        }    
        
        if(max !=i)
        {
        Book temp;
        temp = book[i];
        book[i]=book[max];
        book[max]=temp;
        }
    }
    
    //파일로 출력(저장) 
    for(i=0;i<k;i++)
    {
        fprintf(ofp,"%d. %s - %.0lf원\n", i+1,book[i].title,book[i].tot * 10000.0); 
    }
 
    fclose(ifp);
    fclose(ofp);
    return 0
}
 
//팩 제목이 같으면 가격만 add 
int check(char *title, Book *book, int count)
{
    int i;
    for(i=0;i<count;i++)
    {
        if(strcmp(title,book[i].title)==0)
        return i;//같으면  i번째 
    }
    return -1;//없으면 return
}
cs










#마방진

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include<stdio.h>
#include<string.h>
void magicSquareTest(void);
void setMagicSquare(int (*magic)[19]);
void printArray19(int (*magic)[19]);
int num;
int magic[19][19];
 
int main() {
    magicSquareTest();
    setMagicSquare(magic);
    printArray19(magic);
    
    system("pause");
    return 0;
}
void magicSquareTest(void) {
    printf("inpur number : ");
    scanf("%d",&num);
}
void setMagicSquare(int (*magic)[19]) {
    int count=1,k;
    int i=0,j=num/2;
    
    for (k=0;k<num*num;k++)
    {
        if(count%num==0)
            magic[i++][j]=count;
        else
            magic[i--][j++]=count;
            
        if(i<0)
            i=num+i;
        if(j>num-1)
            j=num-j;
            
        count++;
    }
}
void printArray19(int (*magic)[19]) {
    int i,j;
    for (i=0;i<num;i++
    {
        for (j=0;j<num;j++)
            printf("%5d",magic[i][j]);
        printf("\n");
    }
}
cs



#주민등록번호

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#include<stdio.h>
#include<string.h>
int leap_year(int year);
int strtoNum(char* str);
int formatErrorCheck(char* str);
int dayofmonth[]={0,31,29,31,30,31,30,31,31,30,31,30,31};
int main()
{
    char str[14];
    char flag;
    
    while(1)
    {
        
    printf("\"_\"를 제외한 확인할 주민등록 번호 13자리를 입력하세요 : ");
    gets(str);
        fflush(stdin);
    if(!formatErrorCheck(str))
    {
    printf("검증코드 오류인 주민등록 번호 입니다.\n");
    printf("다시 입력하시겠습니까? (y/n) ");
    scanf("%c"&flag);
     fflush(stdin);
    if (flag == 'Y' || flag == 'y')
    continue;
    else
    break;
    }
 
    else
    {
        printf("올바른 주민등록 번호 입니다.\n");
           printf("다시 입력하시겠습니까? (y/n) ");
    scanf("%c"&flag);
     fflush(stdin);
    if (flag == 'Y' || flag == 'y')
    continue;
    else
    break;
    }
}
    system("pause");
    return 0
}
 
int strtoNum(char* str)
{
    return atoi(str);
}
int leap_year(int year)
{
    if(year >50)
    year =year + 1900;
    else
    year =year + 2000;
    
    if(year%4!=0return 0;
    else if(year%100!=0return 1;
    else if(year%400==0return 1;
    else return 0;
}
 
int formatErrorCheck(char* str)
{
    if(strlen(str) !=13)
    return 0;
    
    char month[10]={0};
    strncpy(month,str+2,2);
    if(strtoNum(month)>12)
    return 0
 
    char day[10]={0};
    char year[10]={0};
    strncpy(year,str,2);
    strncpy(day,str+4,2);
    
    if(leap_year(strtoNum(year)))
    {
        dayofmonth[2]=28;    
    }
    if(strtoNum(day)>dayofmonth[strtoNum(month)])
    return 0;
 
    int magic[12= {2,3,4,5,6,7,8,9,2,3,4,5};
    int i , sum=0;
    int carry;
    for(i=0;i<12;i++)
    {
        sum +=magic[i]*(str[i]-48);
    }
    carry = sum%11;
    if(((11-carry)%10!=(str[12]-48))
    return 0;
    else
    return 1;    
}
cs


'C 언어' 카테고리의 다른 글

[C언어_Day9]파일 입출력  (0) 2018.10.11
[C언어_Day7]동적 할당  (0) 2018.10.11
[C언어_Day6]함수 포인터 + Void 포인터  (0) 2018.10.11
[C언어_Day5]명령 인수, 포인터 사용  (0) 2018.10.11
[C언어_Day4]String 예제  (0) 2018.10.11

■동적 할당■


코딩할 때 지역변수나 매개변수들을 stack에 저장된다 stack에 저장되면 블록을 빠져나가면 사라지게 된다.

반면, 동적 할당은 heap에 저장되어 free명령을 하기 전까지 살아있다.

(프로그램이 종료되면 운영체제가 알아서 free해준다. 하지만 free를 꼭 해주는 습관이 좋다.(그냥 해라)

아마 free를 안해주고 방대한 양이라면 메모리 누수가 생겨 런타임 에러가 발생하면... 상상도 하기 싫다.)


원형을 보면    void *malloc(unsigned int size);    ->size만큼 할당, 시작 위치 반환

(void 포인터를 썻군! 어떤 자료형이 와도 쓸 수 있구만! 대한 casting 해야겟네..)


이외에도 calloc(할당 공간 0으로 초기화), realloc(함수의 크기 조절)도 있습니다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include<stdio.h>
#include<stdlib.h>
 
int main()
{
    char temp[100];
    int i;
    int num=0;
    char *str[num];
    
    printf("문장의 개수 입력 : ");
    scanf("%d",&num);
    
    fflush(stdin);
    
    for(i=1;i<=num;i++)
    {
        printf("%d번째 문장을 입력하세요(99글자까지 입력 가능) :",i); 
        gets(temp);
        printf("\n");
        str[i] = (char *)malloc(strlen(temp)+1); //문자열 끝에 넣어줄 null때문에 +1 
    
        strcpy(str[i],temp);
    }
    
    for(i=1;i<=num;i++)
    {
        printf("%s\n",str[i]);    
        free(str[i]);
    }
    printf("출력이 끝났습니다.\n");
    
    system("pause");
    return 0
}
 
cs

fflush(stdin);는 버퍼를 clear해주는 역할입니다. 이 부분에 대해서는 따로 정리할 겁니다!
간단히 말하자면 버퍼라는 임시 공간이 있는데 키보드로 입력하여 enter 하면 들어갑니다.(공백, 탭, 엔터들도 함께 들어가죠!)
scanf는 공백(스페이스바)을 구분하여 몇 개 인지 구분을 하고 \n(new line)(enter키)를 치면 버퍼에서 가져갑니다.
그래서 예)1 2 3\n

scanf : \n가 있네? \n전까지 가져가야지~ 공백 2개네 3녀석이 들어왔구만!

하고 처리를 합니다. 반면 gets는 문자열을 입력하는 명령어죠! scanf와 다르게 공백까지 저장을 해줍니다.

gets : \n가 있네? 음... 우선 다 가져가자!

라며 "1 2 3"을 들고 옵니다. 하지만 scanf가 가져간 후의 버퍼상태를 보면

버퍼 : \n

되어있어서 gets가 입력 받기도 전에 버퍼에 \n가 남아있기 때문에 아무것도 가져오지 못합니다.

사용자 : (num을 입력했고.. 문장을 입력해볼까? ???뭐야 왜 넘어가지)

gets : \n가 있네? 음... 우선 다 가져가자!(들고 간게 없음..)

이때 fflush(stdin)을 써주면 clear되어 버퍼에 아무것도 남아있지 않습니다.


#끝 말 잇기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
 
int Check(char **str, char *temp, int count);
 
int main()
{
    char temp[80];
    char *str[100= { 0 };
    int i, count;
 
    i = 0;
    while(1)
    {
        printf("단어 입력 :");
        scanf("%s", temp);
        if (!strcmp(temp, "end")) break;
        if( i && (str[i - 1][strlen(str[i - 1]) - 1!= temp[0]))
        {
            printf("단어 잇기가 불가능합니다!\n");    
            continue;
        }
        if(!Check(str,temp,i))
        {
            printf("# 이미 존재하는 단어입니다!\n");
            continue;
        }
            
        str[i] = (char *)malloc(strlen(temp) + 1);
        if(str[i] == NULL)
        {
            printf("> 메모리 부족...\n");
            break;
        }
        strcpy(str[i], temp);
        i++;
    }
    count =i;
    
    for(i=0;i<count;i++)
    {
    printf("%s ",str[i]);
        free(str[i]);
    }
    
    system("pause");
    return 0
}
 
int Check(char **str, char *temp, int count)
{
    int i;
    for(i=0;i<count;i++)
    {
        if(!strcmp(str[i],temp))
        return 0;        
    }
    return 1;
    
}
 
cs


■함수포인터와 void 포인터



# void 포인터


<한 줄 요약>

어떤 자료형이든 가능! 그러나 casting(강제 형변환) 해서 써야만 한다.


즉, void 포인터를 사용하면 유동적으로 사용할 수 있고 함수의 경우 자료형에 따라 만들 함수를 줄여줄 수 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <stdio.h>
#include <string.h>
 
void swap(char *type, void *ap, void *bp);
 
int main(void)
{
    int age1, age2;
    double height1, height2;
 
    scanf("%d%lf"&age1, &height1);
 
    scanf("%d%lf"&age2, &height2);
 
    swap("int"&age1, &age2);
    swap("double"&height1, &height2);
 
    return 0;
}
 
void swap(char *type, void *ap, void *bp)
{
    int temp;
    double dtemp;
 
    if(strcmp(type, "int"== 0)
    {
        temp = *(int *)ap;
        *(int *)ap = *(int *)bp;
        *(int *)bp = temp;
    }
    if(strcmp(type, "double"== 0)
    {
        dtemp = *(double *)ap;
        *(double *)ap = *(double *)bp;
        *(double *)bp = dtemp;
    }
}
cs

#함수 포인터
기능은 다르지만 형태가 같은 함수를 선택적으로 호출할 때 함수 포인터를 쓴다.

자세히는 잘 모르겠지만 뭔가 묶어놓는(?) 느낌이 든다.

폴더 안에 폴더를 만드는 것처럼 이해했다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include<stdio.h>
int sum(int,int);
int sub(int,int);
double mul(double,double);
double div(double,double);
 
int func1(int (*fp)(int,int));
double func2(double (*fp)(double,double));
int main()
{
    printf("%d\n",func1(sum));    
    printf("%lf\n",func2(mul));
    return 0;
}
 
int func1(int (*fp)(int,int))
{
    int a,b;
    printf("정수 입력 :"); 
    scanf("%d%d",&a,&b);
    
    return fp(a,b);
}
 
double func2(double (*fp)(double,double))
{
    double a,b;
    printf("정수 입력 :"); 
    scanf("%lf%lf",&a,&b);
    
    return fp(a,b);
}
 
int sum(int a,int b)
{
    return a+b;
}
 
int sub(int a,int b)
{
    return a-b;
}
 
double mul(double a,double b)
{
    return a*b;
}
double div(double a,double b)
{
    return a/b;
}
cs
이렇게 sum,sub,mul,div라는 기능을 하는 주요 함수가 있고
sum,sub는 int형으로 func1을 통해서 접근하고

mul,div는 double형으로 func2를 통해서 접근하여 사용한다.



함수포인터는 초기화 할 때 매개변수의 자료형과 return의 자료형이 같아야 한다.



1. 단어 추출 프로그램

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include<stdio.h>
 
char *my_token(char *ps);
//char형 주소를 반환하고 char형 포인터 매개변수를 갖는 함수
int main()
{
    char str[80];
    char *p;
    
    printf("문장 입력 : ");
    gets(str);
    
    while((p =my_token(str)) !=NULL)//한문자씩 출력 
    {
    printf("%s\n",p);
    }
    //str이 NULL이 올때가지 실행 즉, 문자열의 끝(NULL)까지 실행 
    return 0;
}
 
char *my_token(char *ps)
{     
    static char* ch = NULL;
    static int end =0;      //정적 지역변수 선언
    char *start; 
    char *count;
    
    if(ps==NULL)
    return NULL;            //문자열이 있는지?
    
    if(end == 1//끝났는지? 
    return NULL;
    
    if(ch ==NULL)//시작  
    start = ps;
    else
    start = ch+1;
    
    count = start;
    
    while(*count !=' '&&*count !='\0')
    count++;
    // 공백 까지 counting
    if(*count =='\0'end =1;//끝 
    else
    *count = '\0';//구분했을때 공백에 null 
    
    ch = count;//위치 넣어줌. 
    
    return start; 
}
cs



■명령 인수


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include<stdio.h>
#include<string.h>
int main(int argc, char **argv) {
    char str[80];
    int num1, num2;
    int i;
    int count;
    int sum=0;
    //cmd 에서 입력 예 : atio 123 4
    //                 ->  argv[0] argv[1] argv[2]
    strcpy(str,argv[1]);
    count = atoi(argv[2]);
    //문자열을 정수로 넣어준다. 
    for (i=0;i<count;i++) {
        num1 = atoi(str);
        printf("\n%s\n",str);
        strrev(str);
        printf("%s\n",str);
        printf("--------\n");
        sum =num1+atoi(str);
        //문자 -> 정수 
        printf("%d\n",sum);
        itoa(sum, str, 10);
    }
}
//atio.exe(실행파일을) cmd의 디렉토리에 마춰서(C:\)넣은후 실행
cs




1. strcmp 구현
flow :  문자열 2개를 받아 한 문자씩 검사

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include<stdio.h>
 
int my_strcmp(char* str1, char* str2);
 
int main()
{
    char str1[80],str2[80];
    int check; 
    
    printf("첫 번재 비교할 문자열 입력 : ");
    gets(str1);
    printf("두 번재 비교할 문자열 입력 : ");
    gets(str2);
    check = my_strcmp(&str1,&str2);
    
    if(check ==1)
    printf("%s가 더 큽니다.",str1);
    else if(check ==-1)
    printf("%s가 더 큽니다.",str2);
    else
    printf("두 문자열이 같습니다.");
 
    return 0;    
}
 
int my_strcmp(char* str1, char* str2)
{
    while((*str1 == *str2 )&&(*str1 !='\0'))
    {
        str1++;
        str2++;    
    }
    
    if(*str1>*str2) return 1;
    else if(*str1<*str2) return -1;
    else return 0;
}
 
 
cs

2. swap

문자열 2개를 받아 한 문자씩 swap

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include<stdio.h>
#include<string.h>
 
void swap(char* str1,char* str2);
 
int main()
{
    char str1[80],str2[80];
    printf("1번 문자열을 입력하세요 : ");
    gets(str1);
    printf("2번 문자열을 입력하세요 : ");
    gets(str2);
    
    
    printf("swap 전 : %s - %s\n",str1,str2); 
    swap(&str1,&str2);
    printf("swap 후 : %s - %s",str1,str2);
    return 0;
}    
void swap(char *pa, char *pb)
{
    char temp;
    while((*pb != '\0'|| (*pa != '\0'))
    {
        temp = *pa;
        *pa = *pb;
        *pb = temp;
        
        pa++;
        pb++;
    }    
}
cs
3. 가장 긴 단어 찾기

getchar로 한문자씩 입력을 받아서 null값전까지 counting한다


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// 가장 긴 단어찾기 프로그램
 
#include <stdio.h>
 
int main(void)
{
    int ch;
    int len, max = 0;
 
    while(1)
    {
        len = 0;
 
        ch = getchar();                    // 문자 입력
        while((ch != -1&& (ch != '\n'))  // Ctrl+Z키를 누르거나 엔터 키를 치지 않는 동안
        {
            len++;                         // 문자의 수를 센다
            ch = getchar();
        }
        if(ch == -1break;                // Ctrl+Z키가 눌려진 경우 입력 종료
        if(len > max) max = len;           // 새로 입력한 단어의 길이가 현재 가장 긴                                            
    }                                      // 단어의 길이보다 길면 그 값을 가장 긴 길이로 설정
    printf("가장 긴 단어의 길이 : %d\n", max);
 
    return 0;
}
cs


+ Recent posts