Prosto

파일 입출력(FILE*) 이해, 예제 -1 -C언어 본문

Programing/C Programing

파일 입출력(FILE*) 이해, 예제 -1 -C언어

Prosto 2016. 9. 17. 02:30

'파일 입출력 - 파일을 생성하고 쓰고, 읽을 수 있는 방법!'

 

프로그래밍을 하다보면 파일을 만들어서 데이터를 보관하는 경우도 있고,

어떤 데이터가 저장된 파일을 읽어와 사용하는 경우도 있습니다.

(C언어에서) 이때 사용하는 것이 바로 파일 입출력입니다.

 

게임으로 예를 들어 싱글플레이 게임이 있는데 사용자가 저장 버튼을 눌러

게임에서 사용되는 레벨, 경험치, 금화, 아이템 등을 저장해야 할 때가 있겠죠?

이때 저장 방법 중 대표적인 방법이 data 파일을 만들어 저장하는 방법이죠.

 

 

우리는 이번에 파일 입출력을 이용하여 몇 가지 정보들을 저장해보기도 하고,

실제로 문제도 풀어보며 파일 입출력을 익혀볼 수 있도록 하겠습니다.

 

 

파일 입출력을 사용하기 위한 가장 기본적인 부분은

 

처리할 파일을 가리키고 있을 파일포인터(FILE *)

해당 파일을 여는데 사용하는 fopen(경로와 파일명, 모드),

파일을 닫는데 사용하는 fclose(파일포인터),

그리고 파일에 출력하는 fprintf, fputs

파일에서 입력을 받아올 수 있는 fscanf 등이 있습니다.

 

 

일단 우리가 한번 간단한 파일을 만들고 저장해볼까요?

 

(주의0. fopen을 그냥 사용하려면 #define _CRT_SECURE_NO_WARNINGS이 필요합니다.) 

(주의1. 파일 디렉토리에 맞는 폴더가 있어야 합니다.)

(주의2. 주 드라이버인 C:\에는 생성이 정상적으로 이루어지지 않습니다. 하위 디렉토리를 이용하세요.)

 

(기본 예제의 소스 코드와 콘솔에서의 결과)

콘솔창에서 완료라는 텍스트가 출력되어 성공적으로 완료되었다고 하네요.

 

해당 소스를 실행시키면 파일이 생성되고 txt 파일에 내용이 있는 모습을 확인할 수 있습니다.

(C:\tempFIO\ 하위에 생성된 "exampleFile.txt"의 모습)

실제로 생성이 잘 된 것을 확인할 수 있습니다.

(exampleFile.txt 파일)

열어서 확인해보면 Example.이라고 우리가 입력한 대로 들어가있죠?

 

 

자 결과는 확인했고, 이제 파일포인터에 관한 부분을 하나씩 집고 넘어가도록 하겠습니다.

 

다시 소스를 보시죠.

 

먼저 FILE *fp;

이 파일포인터는 우리가 만든, 혹은 불러오는 파일에 대한 포인터입니다.(파일 입출력에 꼭 필요하죠.)

우리는 이 파일포인터를 fp라는 이름으로 생성한 것입니다.

 

 

다음으로 fp = fopen("c:\\tempFIO\\exampleFile.txt", "wt");

이는 c:\tempFIO라는 파일 경로에 있는 exampleFile.txt라는 파일을 wt권한(모드)로 열겠다는 의미입니다.

그걸 열어서 fp가 그 위치를 기억하고 있게 해주는 것이죠.

 

첫 번째 인자 값은 파일이 있는 경로와 파일 이름이라고 했죠? 그런데 여기서

"c:\\tempFIO\\exampleFile.txt"와c:\tempFIO\exampleFile.txt의 문자 차이가 보이시나요?

이는 \가 예약된 문자라 그냥 사용이 불가능하여 \\로 사용이 된 것입니다.

(\n \t \" \' 등을 보면 \만 못 쓰겠다는 걸 알겠죠?)

 

여기서 중요한 부분 중 하나가 권한(모드) 부분입니다.

fopen의 두 번째 인자 값이죠.

모드는 r, w, a, rt, wt, at가 있지만, 우리는 일반적으로 wt(fprintf), rt(fscanf)를 사용합니다.

일단 자세한 사항을 한번 읽어보세요.

r은 파일을 읽기만 하는 것이고, w는 파일에 쓰기만 하는 것이고,

a는 w의 확장판으로 지정한 파일이 존재하면 해당 파일 내용 끝부터 데이터를 추가하는 것이죠.

이어 rt는 파일을 읽고 쓸 수 있고, 존재하지 않는 경우 새로운 파일을 생성합니다.

존재하는 경우 데이터 추가 입력 시 원래 파일에 덮어씌워집니다.

wt는 rt와 비슷하지만 파일이 존재하는 경우 모든 데이터를 지우고 데이터를 기록합니다.

at는 rt와 비슷하지만 a와 마찬가지로 끝에서부터 파일 내용 끝부터 데이터를 추가하죠.

 

이 부분에 있어서는 일단은 "wt"를 적어 사용하고, fprintf 기능을 사용할 수 있다고 생각하시면 됩니다.

하지만 읽어들이는 작업을 할 때는 "rt"를 사용합니다.

"wt"와 "rt"로 파일에 쓰기, 읽기가 가능하다 정도만 생각하시면 됩니다.

 

이때 중간에 if(fp == NULL){ //내용 }

이 부분은 예외를 검사하는 부분입니다.

파일이 정상적으로 열렸다면 파일포인터에 그 값이 들어올 텐데요.

여기에 들어오지 않고 NULL값이 있다면 이것은 앞으로 파일포인터를 이용한 작업이 불가능한 상황이죠.

그래서 지금은 printf로 실패하여 종료했다고 출력해주고 return 1;로 프로그램을 종료시켰습니다.

 

 

그럼다음으로 fprintf(fp, "Example.");

여기는 우리가 파일에 print를 해준 곳입니다. Example.이라는 글자를 출력했죠.

그래서 우리가 지정한 경로에 가서 exampleFile.txt를 실행해보면 Example.이라는 글자를 나타내주는 것입니다.

첫 번째 인자는 파일포인터입니다. 어떤 파일에 처리해줄지 정해줘야겠죠.

 

두 번째 인자는 문자열입니다. 문자열을 넣어주면 콘솔창에 나오 듯 파일에 나오는 것이죠.

 

 

그럼 마지막으로 fclose(fp);

우리가 지금까지 사용했던 파일을 열었으니 닫아서 끝내줘야겠죠?

파일에 대한 작업이 끝났으면 해당 파일 포인터를 이용하여 그 파일을 닫아주어야 합니다.

그래야 정상적으로 처리가 되죠.

 

 

이렇게가 우리가 파일 입출력에서 가장 많이 쓰이는 부분들입니다.

파일 입출력의 각 부분들에 대해 이해가 되셨나요?

 

 

그럼 우리가 직접 예제를 하나 더 보며 직접 실행하여 이해해 보도록 합시다.

콘솔 창에서 사용자에게 숫자를 입력받고, 그 숫자를 txt 파일에 넣어보도록 하겠습니다.

 

여기서 보면 숫자를 입력 받았고,

우리가 fprintf로 입력된 숫자까지 파일에 출력해줬죠?

그러면 어떤 결과가 나왔을까요?

그럼 아래의 결과를 확인해보세요.

(추가 예제의 콘솔 창 모습)

 

(생성된 파일에서의 모습)

printf에서 %d를 이용하여 정수를 표현한 것처럼

여러분은 이 예제를 통하여

fprintf에서도 동일한 형식을 이용할 수 있다는 것을 확인할 수 있을 것입니다.

나머지는 앞서 설명한 것과 같았죠?

 

 

 

이제 문제를 통해서 실제로 사용해보도록 하겠습니다.

 

문제1. 두 숫자를 입력받아 더하기,빼기,곱하기,나누기 결과를

c:\tempFIO 경로에 ex3.txt 파일을 만들어 저장하시오.

(콘솔 출력 결과 예)

(생성된 파일 예)

 

문제2. 문자들을 한 번 입력받아 파일로 저장하시오.

(힌트 문자열은 char배열을 사용하고 입력에 gets_s를 사용하면 ' '까지 입력받을 수 있습니다.)

[gets_s(str, 100); 형식입니다. str은 char*이고, 100은 버퍼 사이즈입니다. sizeof(str)로도 사용 가능하죠.]

 

(콘솔 출력 결과 예)

(생성된 파일 예)

 

 

 

결과는 모두 잘 나왔나요?

그럼 이제 제가 작성한 코드와 실행 결과를 올리겠습니다.

비교해보고 참고하세요.

 

 

-1번 문제-

우리가 계산 결과를 printf로 찍은 것과 같은 방법으로 fprintf로 찍어주면 되겠습니다.

 

 

 

-2번 문제-

설명이 조금 필요할 것 같아서 주석을 달아뒀습니다.

참고하시면 되겠네요.

char str[100];//문자 100칸 사용 선언.

gets_s를 이용하여 str에 최대 100칸의 문자열을 입력받음.

 

 

 

지금까지 파일 입출력에 대하여 알아봤습니다.

어떤 것인지부터 예제, 문제까지 풀어봤습니다.

파일 입출력의 이해에 도움이 좀 됐다면 좋겠습니다.

그리고 파일 입출력은 1과 2로 나누어 만들었습니다.

1은 주로 fprintf로 파일에 출력을 시켜주는 것이고

2는 fscanf와 함께 심화 문제까지 다룰 예정입니다.(클릭 시 이동)

 

 

질문은 댓글이나 메일로 따로 연락주시면 시간되는 때 답변드리겠습니다. ( 연락 )

 

Comments