본문 바로가기
대외활동/한화비전 VEDA

1주차 C 공용체,열거형,파일 입출력

by hoshi03 2024. 7. 19.

• 구조체 비트 필드

 

메모리를 몇 비트나 사용할지 정의하는 방법

b1은 4비트, b2는 2비트만 사용하게 정의했다

#define _CRT_SECURE_NO_WARNINGS    
#include <stdio.h>
#include <stdlib.h>
#include <string.h> // strlen 함수 사용을 위해 추가
#include "myList.h"


struct bit {
	unsigned char b1 : 4;
	unsigned char b2 : 2;
} ch;


int main() {
	ch.b1 = 0x0E;
	ch.b2 = 0x00;
	printf("%d\n", sizeof(ch));
	printf("%u, %u\n", ch.b1, ch.b2);
}

 

• 공용체

 

공용체는 멤버간에 메모리를 공유한다

다른 멤버가 메모리를 사용하면 기존 멤버가 사용하던 값이 초기화된다

 

아래의 코드에서는 리틀 엔디안 방식으로 데이터가 저장되어서

 

23 10 .. 형태로 나오게 된다

#define _CRT_SECURE_NO_WARNINGS    
#include <stdio.h>
#include <stdlib.h>
#include <string.h> // strlen 함수 사용을 위해 추가
#include "myList.h"


union student {
	unsigned int addr;
	unsigned char ip[4];
} st ;

int main() {
	// 엔디안
	// 메모리의 낮은 곳, 0번부터 부터 뒤에서부터 들어간다 
	st.addr= 0xc0480a17;
	printf("%d %d %d %d", st.ip[0], st.ip[1], st.ip[2], st.ip[3]);
}

 

• enum

 

enum season {
	SPRING,
	SUMMER,
	FALL,
	WINTER
};

int main() {

	enum seasom ss;
	
	ss = WINTER;
	printf("%d", ss);

	return 0;
}

 

enum안의 문자는 숫자로 취급된다..!

 

• typedef

 

typedef로 별칭을 붙여주는 느낌으로 이해했다

	typedef enum season gyaegeol; // typedef를 이용해서 계절을 정의한 enum seasom을 gyaegeol로 부른다
	gyaegeol a;
	a = FALL;
	printf("%d", a); // FALL에 해당하는 2 출력

 

구조체에도 별칭을 붙일 수 있다

typedef struct {
		int id;
		double height;
	} Members;

 

• 파일 입출력

 

FILE 형 포인터로 사용할 파일을 가져와서 사용한다

fopen(가져올 파일, 가져올 형식) - 파일 열기

fopen 형식 인자로 r w a 중 필요한 걸 넣는다

fputs(입력할 내용, - 파일에 내용 입력)

 

파일을 사용한 후 fclose 로 파일을 닫는다

 

-파일에 텍스트 입력

#define _CRT_SECURE_NO_WARNINGS    
#include <stdio.h>
#include <stdlib.h>


int main()
{
    FILE* fp = fopen("a.txt", "a");

    if (fp == NULL)
    {
        printf("파일 열리지 않음");
        return 1;
    }

    char st[50];
    fgets(st, sizeof(st), stdin);
    fputs(st, fp);
    fclose(fp); 

    return 0;
}

 

- 파일의 텍스트 출력

#define _CRT_SECURE_NO_WARNINGS    
#include <stdio.h>
#include <stdlib.h>


int main()
{
    FILE* fp = fopen("a.txt", "r");

    if (fp == NULL)
    {
        printf("파일 열리지 않음");
        return 1;
    }

    int ch;

    while (1)
    {
        ch = fgetc(fp);
        if (ch == EOF) {
            printf("\n파일 끝\n");
            break;
        }
        putchar(ch); //화면에 입력받은 글자 출력
    }

    fclose(fp);
    return 0;
}

 

- fprintf, fscanf로 파일 내용 쓰고 읽기

 

#define _CRT_SECURE_NO_WARNINGS    
#include <stdio.h>
#include <stdlib.h>

typedef struct type {
    int num;
    double dnum;
    char string[80];
} TYPE;

int main()
{
    TYPE arr = { 10, 1.2345, "hello" }, arr1;
    FILE* fp = fopen("a.txt", "w");

    if (fp == NULL)
    {
        fprintf(stderr, "파일 열리지 않음\n");
        return 1;
    }

    //구조체 내용을 파일에 쓰기
    fprintf(fp, "%d %lf %s\n", arr.num, arr.dnum, arr.string);
    fclose(fp);

    fp = fopen("a.txt", "r");

    if (fp == NULL)
    {
        fprintf(stderr, "파일 열리지 않음\n");
        return 1;
    }

    //파일에서 구조체 내용을 읽어와서 출력하기
    fscanf(fp, "%d %lf %s", &arr1.num, &arr1.dnum, arr1.string);

    printf("%d %lf %s\n", arr1.num, arr1.dnum, arr1.string);
    fclose(fp);

    return 0;
}

 

-fread , fwrite 메서드로 바이트 입출력

#define _CRT_SECURE_NO_WARNINGS    
#include <stdio.h>
#include <stdlib.h>

typedef struct type {
    int num;
    double dnum;
    char string[80];
} TYPE;

int main()
{
    TYPE arr[3] = { {320, 31.2345, "hi"}, {2320, 31.2345, "hi"},{55320, 31.2345, "hi"} }, arr1[3];
    FILE* fp = fopen("a.txt", "wb"); //바이너리 모드로 열기

    if (fp == NULL)
    {
        fprintf(stderr, "파일 열리지 않음\n");
        return 1;
    }

    // fwrite 메서드를 사용할 때는 바이너리 모드로 파일을 열어서 사용한다
    for (int i = 0; i < 3; i++)
    {
        fwrite(&arr[i], sizeof(TYPE), 1, fp);
    }
    fclose(fp);

    fp = fopen("a.txt", "rb");

    if (fp == NULL)
    {
        fprintf(stderr, "파일 열리지 않음\n");
        return 1;
    }

    //파일에서 구조체 내용을 읽어와서 출력하기
    for (int i = 0; i < 3; i++)
    {
        fread(&arr1[i], sizeof(TYPE), 1, fp);

        printf("%d %lf %s\n", arr1[i].num, arr1[i].dnum, arr1[i].string);
    }
    fclose(fp);
    

    return 0;
}

 

- 파일 입출력을 이용해서 노드 데이터 텍스트 파일에 load, save

txt 파일은 이렇게 id와 bookname을 들고 있는 구조 

1 a
22 wasg
2 b
3 c
4 asd
5 ws

 

한줄씩 읽으면서 id와 bookname을 가져오는 방식으로 만들었다

void load(struct link** HEAD, struct link** TAIL) {
    FILE* f = fopen("list.txt", "r");
    if (f == NULL) {
        fprintf(stderr, "파일 열리지 않음\n");
        exit(1);
    }

    int id;
    char bookname[80];
    while (fscanf(f, "%d %s", &id, bookname) != EOF) {
        struct link* newNode = (struct link*)malloc(sizeof(struct link));
        if (newNode == NULL) {
            fprintf(stderr, "메모리 할당 실패\n");
            exit(1);
        }

        newNode->id = id;
        strcpy(newNode->bookname, bookname, sizeof(newNode->bookname) - 1);
        newNode->bookname[sizeof(newNode->bookname) - 1] = '\0'; 
        newNode->next = NULL;
        newNode->prev = NULL;

        if (*HEAD == NULL) {
            *HEAD = newNode;
            *TAIL = newNode;
        }
        else {
            (*TAIL)->next = newNode;
            newNode->prev = *TAIL;
            *TAIL = newNode;
        }
    }

    fclose(f);
}


void save(struct link** HEAD) {
    FILE* f = fopen("list.txt", "w");
    if (f == NULL)
    {
        fprintf(stderr, "파일 열리지 않음");
        exit(1);
    }
    struct link* temp = *HEAD;
    while (temp != NULL) {
        fprintf(f, "%d %s\n", temp->id, temp->bookname);
        printf("%d %s\n", temp->id, temp->bookname);
        temp = temp->next;
    }
    fclose(f);
}