본문 바로가기
[ CODING STUDY ]/》C언어 공부

C언어 20장(파일입출력, fopen, fclose, fprintf, fscanf_s, fgets, fputs, fgetc, fputc, fread, fwrite)

by MRG 2020. 5. 20.
728x90
반응형

▣ 안녕하세요^^ 
저번 시간에 숙제 잘해보셨나요??
이제 코딩이 많이 능숙 해시셨죠??
하지만 아직 어렵다고요? ^^


▣ 네 당연한 것입니다. 
프로그램을 가르치고 게임을 개발하는 저도
매일 공부하는데 어려운 거 같습니다. ^^
그러니 함께 공부하며 파이팅해요.


▣ 오늘은 파일 입출력을 공부해보겠습니다.
표준 입출력이랑 비슷한 부분이 많아서 어렵지 않을 겁니다.
그러니 꼼꼼하게 읽으면서 실습하시면서 공부해주세요.

 

▣ 자 먼저 파일을 제어? 하기 위해 FILE이라는 구조체를 사용해야 합니다. 
FILE에서 오른쪽 마우스를 클릭하고 정의를 들어가면 
이렇게 구조체인 것을 확인할 수 있습니다. 

 

▣ FILE 구조체를 *fp라는 포인터로 선언 및 정의를 하고,
fopen라는 함수를 이용해서 파일을 열어 모드를 적어 읽을지 쓸지 추가할지를 정합니다. 
다시 정리하면 함수 안에 처음에 포인터 주소와, 파일 이름, 그리고 모드를 적어주시면 됩니다.
모드는 내가 파일을 읽고, 쓰고, 추가할지를 정해주는 걸 생각하시면 됩니다.

 

▣ 이렇게 모드에 종류가 있습니다.
잘 보시면 결국
r, w, a == 쓰고, 읽고, 추가만 있는데 어떻게 더 갱신할지 b바이너리 모드인지만 다를 뿐입니다.



▣ fopenf함수를 끝낸다음에 꼭 fclose로 파일을 닫아주셔야 합니다.
그래야 파일이 저장이 됩니다.
우리가 메모리 할당하고 닫았을 때랑 같다고 생각하시면 됩니다.

 

▣ 그런 다음에 디버깅을 하고 설루션 탐색기에서

 

▣ 솔루션 이름에서 오른쪽 마우스를 누르고 탐색기 폴더 열기를 합니다.

 

▣ 그럼 이렇게 현재 프로젝트에 파일이 보입니다.
그걸 더블클릭하면 아까 우리가 만들었던 Player.txt를 확인할 수 있습니다.
더블클릭해서 열어보면 아무것도 없는 걸 볼 수 있습니다.
당연히 아직 아무것도 입력을 주지 않았기 때문이겠죠?



▣ 이번에는 직접 텍스트 파일을 저와 다른 이름으로 만들어보세요.
숙제입니다.



▣ 자 이번에는 우리가 만든 텍스트 파일에 텍스트를 입력해보겠습니다.
코드로 말이죠.

 

▣ 이렇게 하시면 되는데요
fprintf() 어디서 많이 본 함수이죠?
네 printf랑 비슷하다고 보시면 됩니다.
안에 적을 형식이 다를 뿐이죠.
f가 붙으면 파일에 약자라고 생각하시면 되겠네요.
fprintf함수 안에 값은 처음에 파일에 포인터, 그리고 형식, 그리고 그 형식에 따른 값을 적어주면 됩니다.
이렇게 코딩을 하고 디버깅을 해보겠습니다.

 

▣ 그리고 아까처럼 탐색기로 프로젝트에 들어가 만든 Player.txt를 더블클릭해서 열어보면
우리가 넣은 텍스트 글자가 입력된 걸 알 수 있습니다.



▣ 이것도 꼭 직접 해보세요.



▣ 그런데 매번 프로젝트 폴더를 찾아서 열기가 번거롭죠?
코드에서 직접 열게 할 수 도 있습니다.

 

 

▣  이렇게 system함수에서 직접 메모장을 열고 
그다음에 아까 우리가 만든 텍스트 파일 이름을 입력해주고 디버깅을 하면 
이렇게 바로 우리가 만든 파일이 열리는 걸 볼 수 있습니다.
system() 안에 이름이나 확장자가 틀리면 안 되니 오타 주의해주세요.!!!



▣ 그리고 꼭 fclose를 먼저 하고 system을 해주세요
저장을 하지 않고 열면 당연히 에러가 나오겠죠?

 

 

 

▣ 저는 이번에는 scanf_s를 이용해서 
text파일에 글자를 넣어보았습니다. 
이것도 가능하겠죠?
직접 다르게 만들어서 코딩을 해보세요.
제가 해보세요 하는 건 모두 다 필수 숙제입니다. 

 

 

▣ 이번에는 fscanf_s를 사용해서 파일에 있는 문자를 입력받아와 읽어보도록 하겠습니다.
fscanf_s는 scanf_s와 비슷하다고 보시면 됩니다.
fscanf_s은 파일에 있는 내용을 입력을 받아온다라고 생각하시면 됩니다.



▣ 그런데 이 코드에 특이한 점은 fopen이 두 번 진행을 합니다.
네 당연하게도 파일에 내용을 적은 다음에 저장을 하고 
그리고 읽어와야겠죠?
fscanf_s로 입력을 받아오고 파일을 닫고 
printf로 그 값을 출력하는 아주 단순한 코드입니다.
하지만 여기서 주의하셔야 할 건 
꼭 fopen을 하실 때마다 fclose 닫아주셔야 한다는 것 잊지 마세요. 
그래서 두 번째 fopen에서는 모드를 r 읽기 모드로 받아왔습니다.



▣ 단순한 예제지만 꼭 해보세요.

 

 

 

▣ 자 이번에는 fputs와 fgets를 사용해보겠습니다.
이것도 어디서 많이 본 함수이죠?
네 표준 입출력에서
puts와 gets랑 똑같다고 보시면 됩니다.
이 둘은 문자들을 받아오고 출력하고를 생각하시면 되고,



▣ fputc, fgetc는 putchar, getchar와 같다고 보시면 됩니다.
우리는 fputs와 fgets만 다뤄보겠습니다.
fputs로 fp에 문자를 넣어주고 닫은 후에 

 

▣ 다시 파일을 열어 r 모드로 읽은 다음에
whlie문을 활용하여 fgets로 문자 값을 입력을 받았습니다.
while문은 \0 널값까지 while문이 작동하겠죠?
그리고 fclose로 닫아주고
player.txt와 디버깅을 확인해보면
text에 문자 값이 들어있는 걸 확인할 수 있습니다.



▣ 이것도 꼭 직접 다르게 만들어서 해보세요.
표준 입출력이랑 거의 비슷하기 때문에 어렵지 않으실 거라 생각합니다.
fputc와 fgetc도 직접 한번 해보세요.

 

▣ 자 이번에는 fwrite와 fread를 배워보겠습니다.
우리가 파일을 불러올 때 한꺼번에 가지고 오죠?
그래서 문자열에 길이에 따라 메모리에 크기가 달라지는 걸 알 수 있습니다.
하지만 바이너리 모드를 사용할 때에는 정해진 길이만큼 읽고 써야 합니다.



▣ 정리하자면
우리가 지금까지 했던 건 텍스트 모드에서 모든 데이터를 문자 형태로 기록했습니다.
하지만 숫자일 경우에는 다르겠죠?
문자가 아니기 때문에 숫자 그대로를 기록해줘야 합니다.
그럴 때 바이너리 모드를 사용합니다.
바이너리는 메모리에 있는 내용을 그대로 기록하는 걸 의미합니다. 



▣ 그래서 위에 코드에서 wb라는 모드를 사용했죠?
아까 모드 표를 보시면 아시겠지만
b가 붙으면 바이너리 모드입니다. 
그럼 wb는 바이너리 쓰기 모드겠죠?



▣ 그다음에 fwrite로 배열에 있는걸 사이즈만큼 1번 fp에 쓰겠다는 의미가 됩니다. 
그렇게 해서 txt 파일을 확인해보면 제대로 글이 들어가 있는데 
어떤 게 바뀐지는 알 수 없습니다.
다시 밑에 코드를 확인해볼까요?

 


▣ 자 이렇게 puts로 직접 출력해도 잘 나오는 걸 확인할 수 있지만
하지만 어떤 기능인지는 조금 감이 안 잡이시죠?
어떤 변화도 볼 수 없습니다.

 

▣ fread모드도 fwrite모드랑 같이 사용해보겠습니다.
fread로 읽어와서 text를 출력해도 같은 값이기 때문에 어떻게 되는지 알 수 없습니다.
위에 텍스트 모드랑 전혀 다른 게 없어 보입니다.
이렇게 코딩을 하면 알 수 없습니다.



그래서 제가 다른 코드를 한번 작성해보겠습니다.

 

 

▣ 자 이렇게 두 개에 배열을 만들고,
wb모드로 쓰기를 한 후에 fwrite함수를 사용합니다.
fwrite를 해석해보면
number에 있는 4byte만큼씩 5번 number에 값을 fp에 쓰겠다고 코딩을 한 거라고 생각하시면 돼빈다.
그런 다음에 fclose로 닫아주시고요.


▣ 그리고 다시 rb 읽기 모드로 열어서
이번에는 fread로 number 2에 4byte씩 3번 넣겠다. fp에 값을 읽겠다라고 생각하시면 됩니다.
그럼 4byte로 3번 읽어오면 위에서 쓴 number에 10, 20, 30, 40, 50 중에
10, 20, 30만 읽어오겠죠? 
밑에 for문으로 number2에 값을 하나하나 확인해보면 
이렇게 3개에 요소만 바뀌어 있는 걸 알 수 있습니다.
이제 좀 감이 오시죠?


▣ 이것도 직접 다르게 만들어서 바이너리 모드로 fwrite와 fread를 사용해보세요.
숙제입니다. 


▣ 자 오늘은 이렇게 파일 입출력을 배워보았습니다.
표준 입출력과 비슷한 부분이 많아서 어렵지 않았죠?
아주 잘하셨습니다.


▣ 그리고 제가 보안 경고 때문에 _s를 붙인 함수를 사용했지만
#define _CRT_SECURE_NO_WARNINGS을 사용해서
기본 함수를 사용하셔도 됩니다.


▣ 꼭 위에 있는 숙제들 해보시고,
다른 좋은 강사님들 자료와 영상을 함께 공부해주세요.
그리고 질문 있으시면 댓글 남겨주세요.
그럼 다음장에 뵙겠습니다. 



▣ 포기하지 마세요!!! 저도 했습니다!!! 파이팅!!!

 

728x90
반응형

댓글