상세 컨텐츠

본문 제목

C 언어와 파일 입출력, 기본 개념 정리

컴퓨터 관련/프로그래밍 공부

by 열정과 함께 2016. 6. 11. 22:57

본문

C 언어를 통한 파일 입출력으로 .txt file 을 다룰 수 있다. 이에 대한 기본적인 개념을 정리해 봤다. 물론 이거 말고도 많은 기능이 있지만.... 일단 기본적인 읽고 쓰기에 대해 서술했다.


1. 어떻게 열 것인가?

  1) Stream 을 통해 파일을 여는 법

  2) 어디 있는 파일을 열까?


2. 파일을 여는 방식

3. 파일에서 읽어오기

4. 파일로 출력하기

5. 위치 지정자


1. 어떻게 열 것인가?


1) Stream 을 통해 파일을 여는 법

파일을 열고 닫는 함수는 다음의 두 가지다 : fopen / fclose. 이 함수들의 원형은....


fopen("파일 경로", "열기 방식")

fclose(stream 이름)


이렇게 생겼다. 그리고 이 함수들을 쓰기 위해서 아래의 부분이 같이 필요하게 된다.


FILE *(파일이 열릴 포인터 이름 = stream 이름)


즉 정리하면 아래와 같이 된다. file_pointer 의 stream 에 a.txt 라는 파일을 열고자 한다면....


#include <stdio.h>

int main()

{

FILE *file_pointer;

file_pointer=fopen("a.txt", "w");

fclose(file_pointer);

}


이렇게 하면, 이 글에서 다루게 될, 파일을 열고 닫는 기본적인 부분이 완료된다.


2) 어디 있는 파일을 열까?

이 부분은 1) 의 구문 중 fopen 함수에서 "a.txt" 에 대한 부분이다.


아무것도 입력 안 하고 a.txt 라고만 써 두면 기본적인 위치에서 파일을 조작하게 된다. 여기서 말하는 기본적인 위치는 실행하게 될 .exe file 이 있는 위치이다. 즉, 실행파일 옆에 .txt file 이 같이 생기게 된다. 다만 이 작업의 결과는 해당 위치에 a.txt 파일이 있느냐, 없느냐에 따라 달라지게 된다. 자세한 설명은 아래의 부분을 찾아가면 된다.


2. 파일을 여는 방식 


그럼 하던 설명을 이어간다. 일단 위에서 나온 부분을 그대로 반복한다.


#include <stdio.h>

int main()

{

FILE *file_pointer;

file_pointer=fopen("a.txt", "w");

fclose(file_pointer);

}


위와 같은 코드로 만들어진 example.exe 파일을 실행하면 아래와 같은 변화가 생긴다.



이렇게 a.txt 파일이 생겨나는 것을 볼 수 있다. 위 코드에서 파일을 생성하는 기본적인 위치는, 실행 파일과 같은 폴더인 것이다. 그렇다면 다른 경로를 선택하려면 어떻게 하면 될까? 경로 부분을 조절하면 된다. 경로는 일반적으로 아래와 같이 생기지 않았는가?


C:\program files\hidden folder\hidden movie\hidden.mp4


이 부분을 그대로 입력하면 된다. 단 이 때, \ 문자는 그대로 입력하면 경로를 구분하는 문자로 인식하지 못하므로, 아래처럼 한개씩 더 써서 입력하면 된다.


C:\\program files\\프로그래밍 공부\\a.txt


즉, 입력하면 아래와 같이 된다.


#include <stdio.h>

int main()

{

FILE *file_pointer;

file_pointer=fopen("C:\\program files\\프로그래밍 공부\\a.txt", "w");

fclose(file_pointer);

}


2. 파일을 여는 방식


이 부분은 다음 코드에 대한 설명이다.


fopen("a.txt", "w");


여기서 "w" 에 대한 설명이다. 이 부분은 간단히 표로 정리할 수 있다.


모드 

 기능

파일 없음

파일 있음 

 기존 파일 보호
(파일로 출력 시)

 r

읽기(=입력) 

에러 

 기존 파일 이용

 에러

 r+

 읽기/쓰기(=출력)

에러

 기존 파일 이용

겹쳐 써짐

 w

쓰기 

새로 생성

 새로 생성

지워짐(새로 생성)

 w+

쓰기/읽기 

새로 생성 

 새로 생성

지워짐(새로 생성)

 a

쓰기(덧붙이기)

 새로 생성

기존 파일 이용

 뒤쪽에 써짐

 a+

쓰기, 읽기 

 새로 생성

기존 파일 이용

 뒤쪽에 써짐


단, 여기서 입력과 출력이 동시에 가능한 모드에서 입력과 출력을 번갈아 수행하기 위해서는, 위치 지정자를 새로 정해 주어야 한다. 자세한 설명은 아래 부분을 참고.


5. 위치 지정자


3. 파일에서 읽어오기


파일에서 읽어오는 여러 함수들이 있고, 또 읽어오는 방식도 다르지만 일단 아래의 함수에 대해서만 이야기하도록 한다.


fscanf & fgets


이 함수들은 각각 아래와 같은 유형을 가졌다.


fscanf(읽어올 stream name, "읽어올 자료 유형", 읽어들일 위치);

fgets(읽어들일 위치, 읽어올 문자열 크기, stream name)


단, fscanf 는 띄어쓰기나 개행문자, 혹은 파일의 끝을 만나면 더이상의 읽어들이는 작업이 중지되고, fgets 는 개행문자, 파일의 끝 만나면 마찬가지의 일이 발생한다. 여기서 파일의 끝이란 말 그대로 맨 뒤의 문자를 가리키게 된다. 단, 예제의 txt 파일에서 Hello, World! 라 썼다고 해서 '!' 가 파일의 끝이 아니고, 모든 문자가 다 지나가고 난 뒤에 파일의 끝을 별도로 가리키는 문자, EOF(End of File) 가 파일의 끝이 된다. 위의 예제에서는 아래와 같이 활용할 수 있다.


#include <stdio.h>

int main()

{

char from_a_txt[30];

FILE *file_pointer;

file_pointer=fopen("a.txt", "r");

fscanf(file_pointer, "%s" from_a_txt);

printf("읽어온 부분 : %s \n", from_a_txt);

fclose(file_pointer);

return 0;

}


즉, a.txt 를 아래와 같이 만든 뒤 위의 코드를 실행하면



아래와 같은 결과를 출력하게 된다.



일단 위의 부분에서는 fscanf 가 띄어쓰기를 만났기 때문에 중단되어 이렇게 출력이 된 것이다. 당연히 fgets 함수를 써서 출력하면 a.txt 파일에 있는 Hello, World! 를 모두 출력하게 된다.


단, 여기서 5. 위치 지정자 와 관계있는 부분이 하나 있게 된다. 만약 코드를 아래와 같이 만들어서 실행하면 어떻게 될까?


#include <stdio.h>

int main()

{

char from_a_txt[30];

char from_a_txt2[30];

FILE *file_pointer;

file_pointer=fopen("a.txt", "r");

fscanf(file_pointer, "%s" from_a_txt);

printf("읽어온 부분 : %s \n", from_a_txt);

fgets(from_a_txt2, 30, file_pointer);

printf("읽어온 부분 : %s \n", from_a_txt2);

fclose(file_pointer);

return 0;

}


이는 아래와 같은 모습을 보이게 된다. 설명은 후에 이어서.



4. 파일로 출력하기

파일로 출력하는 것은 별 거 아니고 그냥 txt 파일에 새 내용을 써 넣는 것이다. 여기도 다양한 함수들 있지만 일단 아래의 함수에 대해서만 다룬다.


fputs & fprintf


각 함수의 원형은 아래와 같다.


fputs("쓸 내용", 쓸 stream 이름);

fprintf(쓸 위치, "쓸 내용", 서식 문자);


활용하면 아래와 같이 쓸 수 있다.


#include <stdio.h>

int main()

{

char to_a_txt[30]="Good bye, World!";

FILE *file_pointer;

file_pointer=fopen("a.txt", "w");

fputs("Hello, World! ", file_pointer);

fprinf(file_pointer, "Another? %s", to_a_txt);

fclose(file_pointer);

return 0;

}


이렇게 실행한 뒤에 a.txt 파일을 다시 열면 결과는 아래와 같다.



5. 위치 지정자


3. 파일에서 입력받기 의 막바지 부분을 다시 참조하자.



왜 이런 결과가 나왔을까? 바로 위치 지정자 때문이다. 간단히 아래의 부분에서 생각해보면



fscanf 는 , 뒤의 ' ' 띄어쓰기를 만나면서 종료되었다. 그리고 위치 지정자는 띄어쓰기가 있는 칸을 가리키고 있다. 이 상태에서 fgets 가 실행되면 띄어쓰기가 있는 칸부터 다시 입력이 시작되어 위와 같은 결과가 나오게 된다.


위의 상황에서 원하는 결과를 얻기 위해서는, 위치 지정자가 가리키는 위치를 바꿔주면 된다. 사용하는 함수는 fseek 함수인데 이 때, 기준점이 어디냐에 따라 바꾸는 방식을 달리할 수 있다. 기준점의 위치는 아래대로 나눌 수 있다.


1) 파일의 시작

2) 지금 가리키고 있는 위치

3) 파일의 끝


fseek 의 원형과 각각의 경우를 기술하면


fseek(stream_name, offset, 기준점)

  -> offset 은 거리를 나타내는 정수

  -> 파일의 시작 : SEEK_SET

  -> 지금 가리키고 있는 위치 : SEEK_CUR

  -> 파일의 끝 : SEEK_END


즉, 맨 앞에 나왔던 예시에서 fgets 를 이용해 파일의 모든 내용을 출력하기 위해서는 다음과 같이 할 수 있다.


#include <stdio.h>

int main()

{

char from_a_txt[30];

char from_a_txt2[30];

FILE *file_pointer;

file_pointer=fopen("a.txt", "r");

fscanf(file_pointer, "%s" from_a_txt);

printf("읽어온 부분 : %s \n", from_a_txt);

fseek(file_pointer, 0, SEEK_SET);

fgets(from_a_txt2, 30, file_pointer);

printf("읽어온 부분 : %s \n", from_a_txt2);

fclose(file_pointer);

return 0;

}


여기서 만약 offset 을 1 로 바꾼다면, fgets 는 아래의 내용을 출력하게 될 것이다.


ello, World!


이상으로, C 언어를 통한 파일의 입출력의 기본적인 요소들을 간단히 다뤄 보았다.

'컴퓨터 관련 > 프로그래밍 공부' 카테고리의 다른 글

struct(구조체)의 인자 다루기  (0) 2015.04.25
fgets 의 동작  (0) 2015.03.08
char 변수를 int 변수로 바꾸기  (0) 2014.06.26

관련글 더보기

댓글 영역