● 파일이 JPEG 인지 검사하는 프로그램 (목표는 명령줄을 통해 주어진 파일이 JPEG 인지 아닌지 확인해주는 것)
코드를 통해 이미지 파일 형식(JPEG 인지)을 확인할 수 있다.
우선 확인할 JPEG 파일을 cs50 ide 에 저장한다. (왼쪽 파일목록을 보면 jpeg.jpg 파일이 있다.)
1. int main(int argc, char *argv[]) { if ( int argc != 2 ) { return 1; } }
main 함수에 사용자가 프롬프트에 입력할 파일을 받기 위해 int argc와 char *argv[] 를 적어준다.
그리고 프로그램을 실행할 때 프롬프트에 사용자가 파일을 입력했는지 에러를 확인하기 위해 if 문을 작성해서 int argc 가 2가 아니라면 프로그램을 종료한다.
2. FILE *file = fopen(argv[1], "r"); if ( file = NULL ) { return 1 } ; -> 파일을 읽기 모드로 열고 에러 확인
사용자가 입력한 파일명으로 파일을 열기 위해 argv[1] 을 적은 것이고, 이 파일을 읽기 모드로 열기 위해 "r" 을 적는다.
그리고 fopen 으로 반환된 포인터를 file 포인터 변수에 저장한다.
if 문은 에러를 확인하기 위함인데, fopen , get_string, malloc 같이 포인터를 반환하는 함수는 에러가 생기면 NULL 을 반환하기 때문에 file 에 저장된 값이 NULL 이라면 1을 반환하여 프로그램을 종료한다.
3. unsigned char bytes[3]; fread(bytes, 3, 1, file);
우선 char bytes[3] 을 통해 크기가 3인 문자 배열을 만드는데 unsigned 를 붙인 이유는 -128 ~ 127 이 아닌 0 ~ 255 범위의 값을 의미하도록 하기 위함이다. 그리고 여기서 굳이 char 배열을 선택했는데.. 아마 3byte 를 읽어야하기 때문이지 않을까 생각한다. jpeg 파일의 첫 3byte가 고정되어 있기 때문에 이 3byte를 읽기 위해 3byte 크기의 배열을 선언한 것이 아닐까 생각한다. 물론 이건 개인적인 생각이다. 왜 char 를 썼는지 모르겟다... 뭐지;;
fread 함수는 fopen 에 의해 열린 file 의 data 를 읽는 함수이다.
첫 인자로는 배열이 온다. data 를 읽은 memory 의 주소( 첫 byte 주소 ) 가 와야 하기에 bytes 를 적은 것.
2번째 인자로는 읽을 byte 수, 3byte 를 읽을 것이기에 3
3번째 인자로는 읽을 횟수, 1번 읽기 때문에 1
4번째 인자로는 읽을 파일, fopen 에 의해 반환된 FILE 자료형을 가리키는 pointer 를 적어준다. 따라서 file을 적음.
즉, 2줄의 의미는 파일의 첫 3bytes 를 읽는 것이다.
4. if 문
조건식 (bytes[0] == 0xff && bytes[1] == 0xd8 && bytes[2] == 0xff) 의 의미는
모든 jpeg 파일의 첫 3bytes 가 0xff, 0xd8, 0xff 이기 때문에 이를 확인하기 위한 것이다.
이를 통해 사용자가 입력한 파일이 jpeg 인지 확인하는 것이다. 위 3값으로 고정된 이유는 JPEG 개발자들이 정한 일종의 매직 넘버로 파일의 시작점에서 파일이 JPEG 라는 것을 알려주기 위함이다.
따라서, 저 조건식이 맞다면
maybe 를 출력한다. maybe 라고 한 이유는 사실 위 조건 말고도 다른 조건이 있지만 여기선 1가지 조건만을 사용했기 때문에 아마 jpeg 라는 것을 의미한다.
그리고 만약 조건식에 부합하지 않다면
확실하게 jpeg 파일이 아니기에 no 를 출력한다.
위 프로그램을 컴파일한 후 실행해서 ./20-jpeg jpeg.jpg 를 입력한 후 결과가 maybe 가 나온다.
jpeg.jpg 파일은 내가 jpeg 파일을 따로 만들어서 저장한 파일이다. 따라서 maybe 가 나오는 것은 정상적으로 작동하는 것이다.
이렇게 pointer 를 사용하면 파일에 내용을 적을 뿐만 아니라 파일의 data도 읽을 수도 있다.
자료출처 : 부스트코스 - https://www.boostcourse.org/cs112/lecture/119035?isDesc=false
'cs50 기초강의' 카테고리의 다른 글
6. 자료구조 - 배열의 크기 조정하기 (0) | 2021.06.20 |
---|---|
6. 자료구조 - malloc 과 포인터 복습 (0) | 2021.06.20 |
5. 메모리 - 파일 쓰기 (0) | 2021.06.15 |
5. 메모리 - 메모리 교환, 스택, 힙 (0) | 2021.06.14 |
5. 메모리 - 메모리 할당과 해제 (0) | 2021.06.14 |