파일은 크게 두 종류로 나눌 수 있다. 텍스트 파일과 바이너리 파일이다.

 

텍스트 파일은 윈도우의 메모장이나 소스 코드, HTML 파일 같은 종류라 볼 수 있다. 윈도우의 메모장으로 열어볼수 있는 것들은 텍스트 파일류로 볼 수 있다.

 

반면 바이너리 파일은 이미지, 동영상, 데이터 파일등 텍스트 파일을 제외한 거의 모든 파일들이라 볼 수 있다. 바이너리는 0과1의 바이너리(이진) 파일이기 때문에 그 파일의 형식에 맞는 프로그램에서 열람할 수 있다. 바이너리 형식의 파일이 텍스트 파일에 비해서 압도적으로 많다. 그렇지만 텍스트 파일은 별도의 프로그램 없이 사람간의 정보전달이 가능하기 때문에 여전히 중요한 파일 형식이다.

 

C언어에서는 바이너리와 텍스트 파일 형식으로 표현된다.

 

아래의 예제에서 확인할 수 있다. wt 는 파일을 쓰기모드와 Text 모드로 오픈한다. 파일을 여는데 실패하면 NULL 을 반환한다.

 

#include <stdio.h>

void main(){

    FILE *fp1 = fopen("mytextfile.txt","wt");
    if(NULL != fp1)
    {
        int data = 10;
        char ch = 'A';
        fprintf(fp1, "Ready to go, my text file.\n");
        fprintf(fp1, "File testing second line~\n");
        fprintf(fp1, "%d\n",data);
        fprintf(fp1, "%c\n",ch);
        fclose(fp1);
        printf("file open suceed\n");
    }
    char str1[64] ;
    FILE *fp2 = fopen("mytextfile.txt","rt");
    if(NULL != fp2)
    {
        while(NULL != fgets(str1, sizeof(str1), fp2)){
        printf("%s",str1);
        }
        fclose(fp2);
    }
}

* 파일포인터 자료형 FILE은 파일을 조작할 수 있는 정보를 가진 포인터다.

 

파일이 없다면 새로 생성된다. 경로를 입력하지 않으면 실행파일이 있는 그 디렉토리에 파일이 만들어진다.

 

fprintf 는 사용법이 거의 printf 와 같다. C언어는 하드웨어 장치들을 파일처럼 관리한다고 했다. 수많은 장치의 호환성에 일일히 맞추는 프로그래밍이 아니라 하드웨어는 OS가 다루고 C언어는 한단계 높은 추상화를 시켰기 때문이다.

 

어떤 제조사가 만든 하드 디스크건 플로피 디스크건 SSD 건 프로그래머는 파일이라는 한단계 높은 추상화 계층에서 파일을 다룰 수 있다. fprintf 는 텍스트 파일에 기록을 할 수있다. fprintf라는 말에 의미를 두면 파일에 기록한다고 하지 않고 출력한다고 되어있다. 기록하다 write 라는 단어는 바이너리 파일을 다루는 함수의 이름이다. C언어의 관점을 볼 수 있다. 모니터와 파일에는 출력하는 것이지 기록하는 것이 아니다.

 

파일을 열었으면 반드시 닫는 작업도 해야한다. 운영체제가 어느정도 커버하겠지만 파일에 정밀한 조작을 하고 닫지 않으면 운영체제도 복구가 불가능하다.

 

파일을 쓰고 닫았으면 다시 읽기모드로 오픈한다. rt는 read textfile 의 약자이다.

 

마찬가지로 실패하면 NULL을 리턴한다. fgets 와 fscanf 파일이 있는데 fgets 파일이 줄단위로 읽어오는데 유리하다.

 

정상적 실행결과는 아래와 같다. 콘솔에 출력하는 것 뿐이지만 실제 디렉토리에 텍스트 파일이 생성된 것을 확인할 수 있다.

 

 다음은 바이너리 파일을 살펴보자. 바이너리 파일은 텍스트 파일처럼 메모장으로 확인이 어렵다.

 

파일을 저장하고 다시 읽어와야 확인할 수 있다.

 

#include <stdio.h>

void main(){

    int n1[7] = {1,3,5,7,9,11,13};
    FILE *fp1 = fopen("mybinary.dat","wb");

    if(NULL != fp1)
    {
        fwrite(n1, sizeof(int), 7, fp1);
        fclose(fp1);
        printf("file write complete!\n");
    }

    int n2[7] = {0, };
    FILE *fp2 = fopen("mybinary.dat","rb");
    if(NULL != fp2)
    {
        fread(n2, sizeof(int),7,fp2);
        fclose(fp2);
        for (int i=0; i<7; i++)
        {
        printf("%d , ",n2[i]);
        }
    }
}

 

아스키 코드를 저장하고 있는게 아니라 실제 파일의 데이터를 저장하고 있다. 예제에서는 정수형 배열을 만들어 파일에 저장한다. 바이너리 파일을 오픈할 때는 wb 라고 한다. write 모드 binary 의 약자이다.

 

wrtie란 자체가 기록이란 뜻이다. 파일에 기록한다는 뜻이다.

 

매개변수 항목을 보면 첫번째 데이터가 위치한 주소값, 둘째 데이터 단위, 여기서는 32비트 정수형이다. 4바이트이다. 7개의 배열이므로 28바이트에 기록을 한다. 마지막으로 파일 포인터를 넘겨준다.

 

여기까지 저장해서 파일이 생성되었어도 내용의 확인은 안된다. 그럴때는  fread로 파일에서 다시 읽어와야 한다.

 

읽어오는 함수의 매개변수는 기록할 때와 같다. 저장이 성공적이라면 위와 같이 바이너리 파일에서 내용을 가져올 수 있을 것이다.

 

여기까지 이번 C언어 튜토리얼을 마쳐볼까 한다. C언어는 워낙 고전이라 웹페이지 등 자료를 참고할 곳이 많았다. 이지스 퍼블리싱의 C언어 입문도 참고했다. 저자 김성엽 님은 웹페이지와 블로그 카페 등 MS 인도우 프로그래밍을 20년 넘게 히신 분이고 현업에서 왕성하게 활동하시는 분이다. (카페에 가면 소수 개인 교습도 진행한다고 한다.)

 

개인적으로 100프로 만족하지는 않지만 나름 뿌듯함을 느꼇다. C언어 공부는 아직도 갈길이 멀지만 요즘 같은 시대에 컴퓨터 구조에 대해 배울 수 있는 거의 유일한 언어라고 생각하고 기본기를 한번 다지는 계기로 삼았다.

 

C언어에 대하여 아직 다루어야 할 이슈가 많다. 그런 내용들은 다음의 C 튜토리얼이나 소주제 포스팅에서 다루려고 하고 이만 마친다... ㅜ.ㅜ

 

 

공유하기

facebook twitter kakaoTalk kakaostory naver band