상세 컨텐츠

본문 제목

부스트코딩 뉴비챌린지 스터디 5주차 : 파일 쓰기, 읽기, JPEG파일

IT/스터디

by J KIMS 2020. 9. 8. 17:27

본문

반응형

8) 파일 쓰기

 

이번 강의에서 파일 읽기에 대한 설명이 너무 얼렁뚱땅 끝나는 것 같아서 제가 알고 있는 내용을 덧붙여봤습니다.

 

📣 파일 열기

 

FILE *fp;

 

fp는 파일을 가리키는 포인터. 이때 자료형은 FILE 이다.

선언만으로는 아직 어떤 파일도 가리키고 있지 않음.

 

fp = fopen("filename.csv", "w");

 

fopen 함수를 이용해서 파일을 오픈한다. fopen 함수의 인자로 파일명모드를 전달함.

 

파일 모드 기능
"w" 파일을 신규 작성함. 지정한 이름의 파일이 이미 존재한다면 덮어쓰기가 되니 주의.
"r" 기존에 존재하는 파일을 읽어옴 (존재하지 않는다면 에러)

 

아래와 같이 파일명과 모드를 변수로 지정하는 것도 가능하다.

 

FILE *fp;

char mode = "w";
char file_name[] = "name";

fp = fopen(file_name, mode);

 

조금 더 수고를 들여서 파일명을 직접 입력받게 하는 것도 가능.

 

FILE *fp;
char file_name[100];

scanf("%s", file_name);
fp = open(file_name, "w");

 

📣 파일 오픈 시 에러 처리

 

파일 오픈에 실패하면 fopenNULL을 반환한다. exit()는 프로그램을 정상적으로 종료시킨다.

exit()말고 1을 리턴하는 것도 가능.

 

if( (fp = fopen("data", "w")) == NULL) {
	printf("can't open file!\n);
    exit();
}

 

📣 파일 입출력

 

파일 입출력에는 fprintf fscanf함수가 필요하다.

 

// fp가 가리키는 파일에 출력되는 내용을 저장함
fprintf(fp, "%d", i);

// fp가 가리키는 파일에 저장된 내용을 정수로써 data 변수에 저장함
fscanf(fp, "%d", &data);

 

📣 파일 닫기

fclose(fp);

 

보통 코드 마지막에 쓴다.

 

 

이거는 전에 만들어뒀던 코드의 일부분인데 콘솔에서 프로그램을 실행할 때 파일명을 입력하는 방식이다.

ex) ./a.out number.txt

 

메인 함수의 인자인 argv[]라는 배열에 파일명이 저장된다.

무슨 프로그램인지 보다는 파일을 불러오는 방식만 봐주면 좋겠다.

 

#include <stdio.h>
#define SIZE 500000

int main(int argc, char* argv[])
{
    int n,i;
    char *mode = "r";

    printf("숫자의 개수를 입력하세요.: "); 
    scanf("%d", &n);
    //printf("%d\n", n);

    // 1부터 N의 숫자중 K가 빠진 배열
    int partArr[SIZE];
    int lengthOfPartArr = n-1;
    
    // 파일 불러오기
    FILE *fp;
    fp = fopen(argv[1], mode);
    if(fp==NULL) {
        printf("파일을 열 수 없습니다.\n");
        return 1;
    }

    for(i=0; i<=lengthOfPartArr; i++){
        fscanf(fp, "%d", &partArr[i]);
    }

    /* 배열 확인
    for(i=0; i<=lengthOfPartArr; i++){
        printf("%d\n", partArr[i]);
    } */


    fclose(fp);

}

 

 

💡 JPEG 파일의 비밀

 

우리는 앞에서 이미지도 0과 1의 조합으로 되어있다는 걸 배웠다.

JPEG 개발자들이 정한 것으로, JPEG 파일의 첫 세 바이트는 무조건 FF, D8, FF로 시작한다.

이 숫자들을 파일 매직 넘버 혹은 파일 시그니처라고 한다.

 

※ 다른 파일 형식의 시그니처 넘버는 다음 링크(클릭!)에서 확인할 수 있음 (강의 덧글에서 펌)

 

매직넘버를 이용해서 이미지 파일이 jpeg인지 아닌지 구별하는 코드를 작성할 수 있다.

 

#include <stdio.h>

int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        return 1;
    }

    FILE *file = fopen(argv[1], "r");

    if (file == NULL)
    {
        return 1;
    }
 
    unsigned char bytes[3];
    fread(bytes, 3, 1, file);


    printf("Is it JPEG file?\n");
    if (bytes[0] == 0xff && bytes[1] == 0xd8 && bytes[2] == 0xff)
    {
        printf("Yes!\n");
    }
    else
    {
        printf("No\n");
    }

    fclose(file);
}

 

위 코드는 프로그램을 실행할때 콘솔로 파일명을 입력하는 방식이다. ex) ./a.out cat.jpeg

스페이스로 구분되어 argv[] 배열에 저장되기 때문에 argv[1]에 파일명이 저장된다.

 

17열에서 변수를 unsigned로 지정한 것은 표현 가능한 색의 범위는 0~255 사이 이기 때문이다. (음수가 필요없다)

 

fread의 사용 문법은 다음과 같다.

 

fread(배열, 읽을 바이트 수, 읽을 횟수, 읽을 파일);

 

 

cs 유우머 🤣🤣

 

반응형

관련글 더보기

댓글 영역