티스토리 뷰

190615(5일차) - 구조체, 파일입출력

교육을 받으면서 노트필기 했던 내용을 날것 그대로 업로드합니다.
 
전처리기
 

- 복습
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>
#include <string.h>
#include <malloc.h> // malloc 사용시 필요
#pragma warning (disable:4996)
 
main() {
    char buf[100];
    char **p;
    p = (char**)malloc(sizeof(char** 3); // 3개짜리 포인터 배열을 가리키는 포인터.
 
    for (int i = 0; i < 3++i) {
        printf("%d번째 문장 입력 : ",i+1);
        gets(buf); //
        p[i] = (char*)malloc(sizeof(char)*strlen(buf) + 1); // p[i]에 문자열크기만큼 메모리할당 (널문자 포함)
        strcpy(p[i], buf);
    }
    for (int i = 0; i < 3++i) {
        puts(p[i]);
    }
    for (int i = 0; i < 3++i) {
        free(p[i]);
    }
    free(p);
}
cs
 
 
 
- 구조체 정의방법
1
2
3
4
struct Untitled_1
{
    /* data */
};
cs
- 초기화시 {} 사용하여 초기화 가능 {"name", "address", ...}
 
 
- 형식지정자
typedef struct Person {
int age;
}Person;
 
typedef struct{
int age;
}Person;
 
typedef struct Person person; //불완전한 구조체로..
struct Person {// 여기서 완전하게 된다..
int age;
}
 
- 구조체 대입시
값복사가 이루어진다.
문자배열도 복사가능.
 
- 구조체를 함수인자로 전달시
매개변수에 그대로 copy가 되는 것. 전혀 다른 메모리.
함수 내부에서 값을 바꿔도 원본은 바뀌지 않는다.
 
- ex
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
#include <stdio.h>
#include <string.h>
#include <malloc.h> // malloc 사용시 필요
#pragma warning (disable:4996)
 
 
typedef struct num {
    int fir;
    int sec;
}num;
 
void func1(int a, int b) {
    printf("%d + %d = %d\n", a, b, a + b);
}
void func2(num* n) {
    printf("%d * %d = %d\n", n->fir, n->sec, n->fir* n->sec);
}
void func3(num n[]) {
    printf("%d + %d + %d + %d = %d", n[0].fir, n[0].sec, n[1].fir, n[1].sec,
        n[0].fir+ n[0].sec+ n[1].fir+n[1].sec);
}
 
main() {
    num a = { 1,2 };
    num b = { 3,4 };
    num c[2= { 5,6,7,8 };
 
    func1(a.fir, a.sec);
    func2(&b);
    func3(c);
}
cs
1 + 2 = 3
3 * 4 = 12
5 + 6 + 7 + 8 = 26
// *p == p[0]
 
 
 
 
 
 
- 구조체 실제 내부의 크기
word 크기 배수
가장큰 type 배수
default 배수
-> 가장 큰 타입은 한쪽에 몰아 선언하는 것이 효율적 (타입끼리 묶기)
 
 
 
 
 
struct str1{
char a,b,c,d,e;
double arr[2];
char *p;
};
 
struct str2{
int *pp;
char f,g,h,i,j;
STR str1_sr2;
}
cf. #pragma pack(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
#include <stdio.h>
#include <string.h>
#include <malloc.h> // malloc 사용시 필요
#pragma warning (disable:4996)
 
 
 
 
typedef struct bit1 {
    unsigned a : 3;
    signed b : 3;
    int c : 3;
}BIT1;
main() {
    BIT1 v;
 
    char*= (char*)&v;
    char cv;
 
    v.a = 2// 3bit로 2를 표현
    v.b = 1// 3bit로 1을 표현
    v.c = 1// 3bit로 1을 표현
    printf("%d %d %d\n", v.a, v.b, v.c);
 
    cv = *p;
    printf("%x\n", cv);
 
    printf("%x\n"*(char*)&v);
}
cs
little endian.
0100 : 4
1010 : A
 

 
- 공용체
메모리 배치 공간을 공유한다.
같은 주차 공간인데 주간주차, 야간주차, 주말주차.
 
union garage {
int bicycle;
float motorcycle;
char car;
}area;
 
main() {
printf("%d\n", sizeof(union garage)); //4
}
 
 
-구조체 예제
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
#include <stdio.h>
#include <string.h>
#include <malloc.h> // malloc 사용시 필요
#pragma warning (disable:4996)
#define SIZE 3
enum { KOR=0, ENG, MATH, TOTAL, RANK};
 
typedef struct subject {
    int subname[5];// 국어,영어,수학,총점,랭킹
}subject;
typedef struct score { // 성적
    char name[10];
    float avg;
    subject sub;
}score;
main() {
    
    score s[SIZE];
    for (int i = 0; i < SIZE; ++i) {
        printf("%d번째 사람이름 : ", i + 1);
        scanf("%s", s[i].name);
        printf("국어점수 : ");
        scanf("%d"&s[i].sub.subname[KOR]);
        printf("국어점수 : ");
        scanf("%d"&s[i].sub.subname[ENG]);
        printf("국어점수 : ");
        scanf("%d"&s[i].sub.subname[MATH]);
 
        s[i].sub.subname[TOTAL] = s[i].sub.subname[KOR] + s[i].sub.subname[ENG] + s[i].sub.subname[MATH];
        s[i].avg = s[i].sub.subname[TOTAL] / 3.0f;
        s[i].sub.subname[RANK] = 1;
    }
    for (int i = 0; i < SIZE; ++i) {
        for (int j = 0; j < SIZE; ++j) {
            if (s[i].avg < s[j].avg)
                s[i].sub.subname[RANK]++;
        }
    }
 
    printf("성명\t국어\t영어\t수학\t총점\t순위\t평균\n");
    puts("------------------------------------------------------------------------------");
    
    for (int i = 0; i < SIZE; ++i) {
        printf("%s\t%d\t%d\t%d\t%d\t%d\t%f\n", s[i].name, s[i].sub.subname[KOR], s[i].sub.subname[ENG], s[i].sub.subname[MATH],
            s[i].sub.subname[TOTAL], s[i].sub.subname[RANK], s[i].avg);
    }
}
cs
1번째 사람이름 : 홍길동
국어점수 : 10
국어점수 : 20
국어점수 : 30
2번째 사람이름 : 이순신
국어점수 : 30
국어점수 : 30
국어점수 : 20
3번째 사람이름 : 둘리
국어점수 : 90
국어점수 : 20
국어점수 : 10
성명 국어 영어 수학 총점 순위 평균
------------------------------------------------------------------------------
홍길동 10 20 30 60 3 20.000000
이순신 30 30 20 80 2 26.666666
둘리 90 20 10 120 1 40.000000
 
 
 
- 구조체 예제
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
#include <stdio.h>
#include <string.h>
#include <malloc.h> // malloc 사용시 필요
#pragma warning (disable:4996)
 
struct engine {
    int piston;
    int fan;
    int pipe;
};
struct car {
    struct engine *sedan, *sports;
};
void hyundai(struct car * man) {
    struct engine*= man->sedan;// 체이닝 제거
    p = (struct engine*)malloc(sizeof(struct engine));
    p->piston = 50;
    p->fan = 30;
    p->pipe = 20;
}
void main() {
    struct car hi;
    hyundai(&hi);
    printf("%d %d %d \n", hi.sedan->piston, hi.sedan->fan, hi.sedan->pipe);
}
cs
 

 
- 파일 입출력
 
키보드와 메모리 사이에 입력에 관한 논리적 접속이 있다. (이를 표준 입력 스트림이라고 한다.)
 
메모리에서 디스크로의 입출력은 직접 user가 만들어야 한다. 입력용, 출력용을 따로 만든다. (FILE *p; p=fopen("a.txt", "w");
p를 통해서 a를 쓰겠다.
 
fprintf(stdout, "%s", name); 모니터로 출력하는 함수
 
 
- ex Read
p=fopen("a.txt","r");
fscanf(p,"%s",name);
 
파일에 접근하려면 p를 통해 접근해야 한다.
 
 
 
 
기존파일있음
기존파일없음
"r"
읽기모드
열림
NULL반환
"w"
삭제후에 쓰기모드
삭제 후 쓰기
새파일생성
"a"
추가모드
파일 끝에 추가
새파일생성
"r+"
읽기/ 쓰기
 
 
 

 
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 <string.h>
#include <malloc.h> // malloc 사용시 필요
#pragma warning (disable:4996)
 
main() {
    FILE * fp;
    fp = fopen("a.txt""w"); // 없으면 생성 , 삭제후 쓰기
    fprintf(fp, "%d %s \n"10"aaa");
    fprintf(fp, "%d %s \n"20"bbb");
    fclose(fp);
 
    int num;
    char str[20];
    fp = fopen("a.txt""r");
 
    fscanf(fp, "%d %s"&num, str);
    fprintf(stdout, "%d %s\n", num, str);
 
    fscanf(fp, "%d %s"&num, str);
    fprintf(stdout, "%d %s\n", num, str);
    fclose(fp);
 
    fp = fopen("a.txt""a");
    fprintf(fp, "%d %s \n"30"ccc");
    fclose(fp);
 
    printf("----출력하기----\n");
 
 
    fp = fopen("a.txt""r");
    while (fscanf(fp, "%d %s"&num, str)!=EOF) {
        fprintf(stdout, "%d %s\n", num, str);
    }
    fclose(fp);
}
cs
- 실패하면 NULL을 반환한다. fopen
 

 
//
//a 10 20 good morning!
 
#include <stdio.h>
#include <stdlib.h>
 
int main(void) {
FILE *in=NULL;
FILE *out=NULL;
int a, b;
char c;
char s[20];
in = fopen("a.txt", "r");
 
fscanf(in, "%c %d %d", &c, &a, &b);
fgets(s, 20, in);
fclose(in);
 
out = fopen("b.txt", "w");
fprintf(out, "%c %d %d %s\n", c, a, b, s);
fprintf(out, "%s", s);
fprintf(out, "%s", s);
fclose(out);
 
out = fopen("b.txt", "a");
fprintf(out, "- %s -", "the end");
fclose(out);
}
 

 
fflush() 출력스트림과 파일의 동기화
 
- 이미지 복사
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
#include <stdio.h>
#include <string.h>
#include <malloc.h> // malloc 사용시 필요
#pragma warning (disable:4996)
 
 
 
main() {
    char buf[100];
    int cnt;
    FILE* frp, *fwp;
    frp = fopen("1.png""rb"); // "r" == "rt"(default) // b:binary
    fwp = fopen("2.png""wb");
    float totalByte = 0;
    while (1) {
        cnt = fread(buf, 1100, frp); //frp로부터 100개를 1byte씩 읽어 버퍼에 넣겠다는 뜻.
        // 읽은 개수를 반환함.
        if (cnt < 100) {//깨졌거나 끝이거나
            if (feof(frp)) { // 남은 짜투리 공간 복사
                totalByte += cnt;
                fwrite(buf, 1, cnt, frp);
            }
            else {
                puts("복사 실패");
                return;
            }
            break;
        }
        totalByte += 100;
        fwrite(buf, 1100, fwp);
    }
    printf("총 %.3fKB 복사\n", totalByte/1000);
    fclose(frp);
    fclose(fwp);
}
cs
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>
#include <string.h>
#include <malloc.h> // malloc 사용시 필요
#pragma warning (disable:4996)
 
 
 
 
 
main() {
    FILE *p;
    p = fopen("test.txt""w");
    char buf[100];
    for (int i = 0; i < 4++i) {
        scanf("%s", buf);
        fprintf(p, "%d. %s\n", i + 1, buf);
    }
    fclose(p);
}
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
main()
{
    FILE* in = NULL;
    FILE* out = NULL;
 
    int a;
    int i = 0;
 
    in = fopen("a.txt""r");
    out = fopen("b.txt""w");
 
    a = fgetc(in);
    while ((a != EOF)) {
        static int flag = 0;
        if (a != '\n' && flag==0){
            fprintf(out"%d : ", i++);
            flag = 1;
        }
        if (a == '\n')
            flag=0;
        fputc(a, out);
        a = fgetc(in);
 
    }
    fclose(in);
    fclose(out);
}
cs
 
 
- bit연산자
#include <stdio.h>
#include <string.h>
#include <malloc.h> // malloc 사용시 필요
#pragma warning (disable:4996)
 
 
 
//bit check : 1이냐 0이냐
 
//bit mask : 해당 비트열을 골라서 볼 때
 
//bit set : 해당 비트열을 1로 셋팅할 때
 
//bit clear : 해당 비트열을 지울 때 (0)
 
main() {
int a = 0x12345678;//... 0111 1000
 
if ((a & 8) != 0) // if &를 사용하면 check를 할 수 있다.
puts("true");
a = a & 24;
// ... 0111 1000
// & 0001 1000
//= 11000 (24)
 
///// a = a&(3<<3); // a = a & 24
///// 11 <<3 -> 11000
printf("%d\n", a); //24
 
 
//set
a = 0x12345678;
a = a | 128; // bit set
printf("%x\n", a);
 
a = a & ~96;//clear (~:not)
printf("%x\n", a); // 0x123456F8
 
}
 
 
 
 
- 비트연산
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
#include <stdio.h>
#include <string.h>
#include <malloc.h> // malloc 사용시 필요
#pragma warning (disable:4996)
 
 
/*
int a=0x45
int *p를 이용해서 a의 내용 변경하고 출력.
(비트는 우측에서부터 0부터시작)
 
1. 6번비트 0? 0이면 false
2. 3번비트와 1번비트를 1로 set
3. 1번비트와 2번비트를 0으로 clear
4. 567비트를 추출하여 값출력.
 
7654 3210
1010 0101
 
0010 1101
*/
main() {
    int a = 0x45;
    if (a & 32 != 0)
        printf("false\n");
    else
        printf("true\n");
 
    //a = a | 9;
    //또는
    a |= (1 << 3+ (1 << 1);
    printf("%x\n",a);
    
    //a &= (~5);
    //printf("%x\n", a);
    //또는
    a &= ~((1 << 1+ (1 << 2));
    printf("%x\n", a);
 
    
    //printf("%x\n", a & 224);
    //또는
    a &= (0x7 << 5);
    printf("%x\n", a);
}
cs
 
 

 
 
 
- 매출
item.txt
//////////////////////////////
전자레인지 88
공기청정기 191
일반형냉장고 338
노트북5 798
지펠 920
갤럭시A7 1022
LEDTV 260
갤럭시s7 190
DVD 65
멀티형에어컨 1653
김치냉장고 456
스탠드형선풍기 46
전기오븐 458
업소형냉장고 1187
일반용제습기 173
진공청소기 183
일반세탁기 489
드럼세탁기 863
레이져프린터 122
 
 
 
 
sales.txt
///////////////////////////////
멀티형에어컨 1980
김치냉장고 30
스탠드형선풍기 809
전기오븐 77
업소형냉장고 303
일반용제습기 26
지펠 123
갤럭시A7 1654
LEDTV 221
갤럭시s7 2034
DVD 12
진공청소기 456
일반세탁기 421
드럼세탁기 396
레이져프린터 324
전자레인지 55
공기청정기 3045
일반형냉장고 78
노트북5 875
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
#include <stdio.h>
#include <string.h>
#include <malloc.h> // malloc 사용시 필요
#pragma warning (disable:4996)
 
 
 
typedef struct sales {
    char name[50];
    int price;
    int num;
    int total;
}sales;
 
main() {
    sales s[19];
    FILE* p = fopen("item.txt","r"); // 가격이있는 파일 읽기
    char buf[100];
    int num;
    int i = 0;
    int sum = 0;
    while (fscanf(p, "%s %d", buf, &num)!=EOF) {
        strcpy(s[i].name, buf); // 이름은 문자열 복사
        s[i].price = num; // 가격은 대입
        i++;
    }
    for (int i = 0; i < 19++i) { // 전부 출력
        printf("%s\t%d\n", s[i].name, s[i].price);
    }
    fclose(p); // 끊기
 
    p = fopen("sales.txt""r"); // 팔린 개수가 있는 파일 열기
    while (fscanf(p, "%s %d", buf, &num) != EOF) {
        /*strcpy(s[i].name, buf);
        s[i].num = num;
        i++;*/
        for (int i = 0; i < 19++i) {
            if (strcmp(s[i].name, buf) == 0) { // 아까 읽었왔던 상품명과 비교해서 같으면 데이터 추가
                s[i].num = num;//팔린수량 추가
                sum+=s[i].total = num * (s[i].price);//총계추가, 매출합계계산
            }
        }
    }
 
    puts("___________________________________________");
    for (int i = 0; i < 19++i) { // 출력.
        printf("name:%11s\tprice:%d\tnum:%5d\tsum:%d\n", s[i].name, s[i].price,s[i].num,s[i].total);
    }
    puts("___________________________________________");
    printf("매출합계 : %d\n", sum);
    fclose(p);
}
cs
전자레인지 88
공기청정기 191
일반형냉장고 338
노트북5 798
지펠 920
갤럭시A7 1022
LEDTV 260
갤럭시s7 190
DVD 65
멀티형에어컨 1653
김치냉장고 456
스탠드형선풍기 46
전기오븐 458
업소형냉장고 1187
일반용제습기 173
진공청소기 183
일반세탁기 489
드럼세탁기 863
레이져프린터 122
___________________________________________
name: 전자레인지 price:88 num: 55 sum:4840
name: 공기청정기 price:191 num: 3045 sum:581595
name:일반형냉장고 price:338 num: 78 sum:26364
name: 노트북5 price:798 num: 875 sum:698250
name: 지펠 price:920 num: 123 sum:113160
name: 갤럭시A7 price:1022 num: 1654 sum:1690388
name: LEDTV price:260 num: 221 sum:57460
name: 갤럭시s7 price:190 num: 2034 sum:386460
name: DVD price:65 num: 12 sum:780
name:멀티형에어컨 price:1653 num: 1980 sum:3272940
name: 김치냉장고 price:456 num: 30 sum:13680
name:스탠드형선풍기 price:46 num: 809 sum:37214
name: 전기오븐 price:458 num: 77 sum:35266
name:업소형냉장고 price:1187 num: 303 sum:359661
name:일반용제습기 price:173 num: 26 sum:4498
name: 진공청소기 price:183 num: 456 sum:83448
name: 일반세탁기 price:489 num: 421 sum:205869
name: 드럼세탁기 price:863 num: 396 sum:341748
name:레이져프린터 price:122 num: 324 sum:39528
___________________________________________
매출합계 : 7953149
 
 
 
 
 
 
 
 
 
댓글
댓글쓰기 폼
네이버 이웃추가
«   2019/10   »
    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    
글 보관함