로그인

검색

C/C++
2013.07.28 03:02

파일 입출력

MoA
조회 수 1188 추천 수 0 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 게시글 수정 내역 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 게시글 수정 내역 댓글로 가기 인쇄

http://kid1412org.tistory.com/21


파일의 개방(Open)과 종결(Close)

  • 파일의 개방(open)

    • 파일을 개방한다는 의미는 파일과 데이터를 주고 받을 수 있는 스트림을 생성한다는 뜻
    • fopen : #include<stdio.h> FILE* fopen(const char* filename, const char* mode);이 함수 원형이다.

      • filename은  open 시킬 파일의 경로이다.
      • mode는 oper시킬 파일을 어떤 식으로 열지에 대한 것이다.

 

  • 파일 접근 모드

    • r : 파일을 읽기 위해서 개방한다. only read
    • w : 데이트를 쓰기 위해서 개방한다. only write, 지정해준 파일이 없을 경우 알아서 생성한다.
    • a : 지정해준 파일이 존재하면 데이터를 지우지 않고 그 파일의 끝에서부터 데이터를 추가한다.
    • r+ : 읽고 쓰기 위해 개방한다. 파일이 존재 안할경우 생성하고, 존재할 경우 파일을 지우기는 않고 덮어쓴다.
    • w+ : r+ 모드와 달리 파일이 존재하면 파일 자체를 지워버리고 기록한다.
    • a+ : r+ 모드와 달리 파일이 존재파면 파일의 끝에서부터 데이트를 추가한다.

 

  • 데이터 입.출력 모드

    • t : 텍스트모드
    • b : 2진 모드
    • CR : 특수문자 'r'로 표현되며, 커서의 위치를 그 줄 매 앞으로 이동하라는 의미이다.

#include <stdio.h>
int main()
{
 printf("ABCDEFGr");
 printf("1234567 ");
 return 0;
}

  • 위의 소스에서 보면 r를 써서 ABCDEFG를 찍고 나서 커서를 맨 앞으로 옮기고 그다음에 1234567를 찍기 때문에 ABCDEFG가 사라진다.

    • LF : 특수문자 'n'로 표현되며 커서의 위치를 그 다음 줄로 이동하라는 의미이다. 단, 커서의 위치까지 맨 앞으로 이동하라는 뜻은 아니다


      #include <stdio.h>
      int main()
      {
       printf("ABCDEFGn");
       printf("1234567 ");
       return 0;
      }

  • 위와 같은 소스의 결과를 보면 n에 대한 그림처럼 나오지 않고 rn이 합쳐진 결과값이 나온다.

    • 이유는 아래쪽에서 설명하겠다.

 

  • 텍스트 모드와 2진 모드

    • 2진 모드 : 프로그램상에서 파일로 데이터를 쓰거나 읽어 들이는 경우에 아무런 데이터의 변환도 일으키지 않는 데이터 입출력모드
    • 텍스트 모드 : 프로그램상에서 파일로 데이터를 쓰거나 읽어들이는 경우에 데이터 변환이 일어나는 입출력 모드
    • 텍스트 모드일때 C프로그램에서 n는 rn으로 변형되서 인식을 한다.
    • 따라서 문자열과 같은 텍스트 기반의 데이터는 텍스트 모드로
    • 데이터의 변환이 발생하면 안되는 경우(영상 데이터 입출력 같은)에는 2진 모드로 데이터를 입출력해야한다.

 

  • 파일 개방 모드의 완성

    • 여기서 말하고 싶은건 위에서 파일접근모드와 데이터 입.출력모드의 구성을 조합해서 쓸수 있다는 내용이다.

 

  • FILE 구조체의 포인터(파일 포인터)

    • 지정한 파일과의 데이터 입.출력을 위해 스트림을 생성하는 함수이다.
    • 리턴 값은 무엇인가?

      • FILE이라는 구조체 변수의 포인터이다.
      • FILE 구조체 변수는 개방한 파일에 대한 여러가지 정보를 지니는 변수이다.
    • 무슨 목적으로 사용하게 되는가? 

      •  데이터를 입.출력할때 : FILE 구조체 변수를 참조하면 데이터를 입출력할 파일이 무엇인지 알 수 있다.
      • 위치 정보를 참조 할 때 : FILE 구조체 변수는 파일 내의 위치 정보를 지니고 있다. 이를 참조하면 해당 파일의 어느 위치까지 데이터를 입력 혹은 출력했는지 알 수 있다.
      • 파일의 끝을 확인 할 때 : FILE 구조체 변수를 참조하면 파일의 끝까지 데이터를 읽어 들였는지에 대한 정보를 알 수 있다.

 

  • 파일의 종결(close)

    • fclose : #include<stdio.h> int fclose(FILE* stream)이 함수원형이며 해당 스트림을 소멸 하는게 역할이다.

 #include <stdio.h>
int main()
{
 int state;
 FILE* file = fopen("Test.txt","wt");
 if(file==NULL)
 {
  printf("file open errorn");
  return 1;
 }
 state = fclose(file);
 if (state!=0)
 {
  printf("file close error!n");
  return 1;
 }
 return 0;
}

  •  위에서 오픈모드를 wt로 하였기 때문에 Test.txt라는 이름의 파일이 존재하지 않으면 현재 디렉토리에 파일이 생성될 것이다.

 

II. 파일 입.출력 함수

 

기능 / 스트림키보드/모니터선택(키보드/모니터,파일)
 문자 출력int putchar(int c)int fputc(int c,FILE* stream)
 문자 입력int getchar(void)int fgetc(FILE* stream)
 문자열 출력int puts(cpmst char* s)int fputs(const char*s, FILE* stream)
 문자열 입력char* gets(char* s)char* fgets(char* s,int n,FILE* stream)
 형식 지정 출력int printf(const* format,...)int fprintf(FILE* stream,const char* format,...)
 형식 지정 입력 int scanf(const char* format,...)int fscanf(FILE* stream, const char* format,...)
   
  • fputs 함수를 이용한 파일 출력

#include <stdio.h>
int main()
{
 int state;
 FILE* file = fopen("Test.txt","wt");
 if (file==NULL)
 {
  printf("file open error!n");
  return 1;
 }
 puts("Dont's Worry!");
 fputs("Dont's Worry!n",stdout);
 fputs("Dont's Worry!n",file);
 state = fclose(file);
 if (state!=0)
 {
  printf("file open error!n");
  return 1;
 }
 return 0;
}

  • puts로 문자열을 모니터에 찍고, fputs로 스트림이 stdout이니까 모니터에 출력하고 그다음 fputs에서 스트림이 file이므로 Test.txt  파일에 저장한다.

 

  • fgets 함수를 이용한 파일 입력

#include <stdio.h>
int main()
{
 int state;
 char buf[30];
 FILE* file = fopen("Test.txt","rt");
 if (file==NULL)
 {
  printf("file open error!n");
  return 1;
 }
 fputs("데이터 입력:",stdout);
 fgets(buf, sizeof(buf),stdin);
 puts(buf);
 fgets(buf,sizeof(buf),file);
 puts(buf);
 state = fclose(file);
 if (state!=0)
 {
  printf("file open error!n");
  return 1;
 }
 return 0;
}

  • fgets로 먼저 키보드에서 받아드린 값을 puts로 모니터상에 출력을 하고 두번째 fgets는 file로 부터 문자열을 읽어와서 puts로 출력을 한다.(Test.txt 파일안에 글이 있다면 화면에 찍힌다.)

    • 위 소스에서 문제점은 만약 배열의 크기를 넘어 가면 어떻게 할것인가 이다.
    • 따라서 파일의 끝에 도달했을음 확인할 방법을 찾으면 된다.

 

  • fprintf와 fscanf 함수를 이용한 파일 입.출력

#include <stdio.h>
int main()
{
 int state;
 int i,j;
 int a=0,b=0,c=0;
 char c1=0,c2=0;
 FILE* file = fopen("Test.txt","wt");
 if (file==NULL)
 {
  printf("file open error!n");
  return 1;
 }
 for(i = 2;i<10;i++)
  for(j=1;j<10;j++)
   fprintf(file,"%d * %d = %dn",i,j,i*j);
 state = fclose(file);
 if (state !=0)
 {
  printf("file close error!n");
  return 1;
 }
 file = fopen("Test.txt","rt");
 if (file == NULL)
 {
  printf("file open error!n");
  return 1;
 }
 for(i=2;i<10;i++)
  for (j=1;j<10;j++)
  {
   fscanf(file,"%d %c %d %c %d",&a,&c1,&b,&c2,&c);
   printf("%d %c %d %c %dn",a,c1,b,c2,c);
  }
  state = fclose(file);
  if(state!=0)
  {
   printf("file close error!n");
   return 1;
  }
  return 0;
}

  • 파일 입.출력 함수와 FILE 구조체 변수

    • 파일 위치 지시자 : 파일을 어디까지 읽었는지, 어디까지 썼는지 그 위치를 기억하고 있다는 뜻 이러한 정보를 기억하고 있는 변수

 

III. 파일의 끝을 확인합시다.

  • 리턴 값을 참조하는 방법

 

함수파일의 끝에서 리턴 되는 값
 fgetc EOF(-1)
 fgets NULL 포인터(0)
 fscanf

 EOF(-1)



#include<stdio.h>
int main()
{
 int state;
 char* pState;
 char str[20];
 FILE* file = fopen("Test.txt","rt");
 if (file==NULL)
 {
  printf("file open error!n");
  return 1;
 }
 while (1)
 {
  pState = fgets(str,sizeof(str),file);
  if (pState == NULL)
   break;
  fputs(str,stdout);
 }
 state = fclose(file);
 if (state!=0)
 {
  printf("file close error!n");
  return 1;
 }
 return 0;
}

  • while 문에서 파일의 끝이 나올때 까지 반복하면서 데이터를 읽어 들인다.(참고로 이전에 만들어진 구구단 test.txt를 가지고 하는 것이다.)

 

#include <stdio.h>
int main()
{
 int state;
 char ch;
 FILE* file = fopen("Test.txt","wb");
 if (file==NULL)
 {
  printf("file open error!n");
  return 1;
 }
 fputc('1',file);
 fputc((char)255,file);
 fputc('2',file);
 state=fclose(file);
 if (state!=0)
 {
  printf("file close error!n");
  return 1;
 }
 file = fopen("Test.txt","rb");
 if (file==NULL)
 {
  printf("file open error!n");
  return 1;
 }
 while (1)
 {
  ch = fgetc(file);
  if (ch == -1)
   break;
  printf("data : %cn",ch);
 }
 state = fclose(file);
 if (state!=0)
 {
  printf("file close error!n");
  return 1;
 }
 return 0;
}

  • 결과값을 찍어 보자

    • 위에서 1, (char)255, 2 를 저장하였음에도 불구하고 1만 출력되는 것을 볼 수 있다.
    • (char)255는 10진수로 -1이다. 그런데 while문에서 -1이 file 안에 있다면 반복문을 빠져 나오는 것인데 (char)255를 -1으로 인식하여 종료가 되는 것이다.

 

#include <stdio.h>
int main()
{
 int state;
 int ch;
 FILE* file = fopen("Test.txt","wb");
 if (file==NULL)
 {
  printf("file open error!n");
  return 1;
 }
 fputc('1',file);
 fputc((char)255,file);
 fputc('2',file);
 state=fclose(file);
 if (state!=0)
 {
  printf("file close error!n");
  return 1;
 }
 file = fopen("Test.txt","rb");
 if (file==NULL)
 {
  printf("file open error!n");
  return 1;
 }
 while (1)
 {
  ch = fgetc(file);
  if (ch == -1)
   break;
  printf("data : %cn",ch);
 }
 state = fclose(file);
 if (state!=0)
 {
  printf("file close error!n");
  return 1;
 }
 return 0;
}

  •  위 소스는 이전 소스에서 char ch를 int ch로 바뀐 점이다.

    • 여기에 대한 설명은 아직 제대로 이해를 못해서 책을 봐주세요 ;;;

 

  • feof 함수를 사용하는 방법

    • feof : #include<stdio.h> int feof(FILE* stream)이 함수 원형이며 호출시 전달되는 파일 포인터가 가리키는 파일이 끝에 도달한 경우 0이 아닌 값을 리턴한다.

 

#include <stdio.h>
int main()
{
 int state;
 char ch;
 FILE* file = fopen("Test.txt","wb");
 if (file==NULL)
 {
  printf("file open error!n");
  return 1;
 }
 fputc('1',file);
 fputc((char)255,file);
 fputc('2',file);
 state=fclose(file);
 if (state!=0)
 {
  printf("file close error!n");
  return 1;
 }
 file = fopen("Test.txt","rb");
 if (file==NULL)
 {
  printf("file open error!n");
  return 1;
 }
 while (1)
 {
  ch = fgetc(file);
  if (feof(file)!=0)
   break;
  printf("data : %cn",ch);
 }
 state = fclose(file);
 if (state!=0)
 {
  printf("file close error!n");
  return 1;
 }
 return 0;
}


  • 책에서 나온 실행 결과는 잘못된 것이고 p.558에 있는 실행결과처럼 나와야 한다.

    • 이전 소스에서는 while문 안에 if(ch == -1) 일때 반복문을 빠져 나오게 하였지만 좋지 못한 결과가 나오기도 했다.

      • 그러나 feof를 써서 0이 아닌 값 즉 파일의 끝에 도달하면 0이 아닌 값을 리턴 할때 반복문을 빠져 나오게 한다.

 

IV. Random Access 파일 입.출력

  • fseek : #include<stdio.h> int fseek(FILE* stream, long offset, int wherefrom)이 함수원형

    • 파일 위치 지시자를 원하는 위치에 놓을 수 있다.  stream이 가리키는 파일의 파일 위치 지시자를 시작 위치 wherefrom에서부터 offset 만큼 이동한다.
만약에 wherefrom이파일 위치 지시자를 offset 만큼 이동하기 전에
 SEEK_SET(0)이라면 파일의 맨 앞으로 이동한다.
 SEEK_CUR(1)이라면 이동하지 않는다.
 SEEK_END(2)이라면

 파일의 끝으로 이동한다.




#include <stdio.h>
int main()
{
 char buf[10];
 FILE* file = fopen("Test.txt","wt");
 fputs("1234abcd56789",file);
 fclose(file);
 file = fopen("Test.txt","rt");
 fgets(buf,7,file);
 printf("%sn",buf);
 fseek(file, 2, SEEK_CUR);
 printf("%cn",fgetc(file));
 fseek(file,-2,SEEK_CUR);
 printf("%cn",fgetc(file));
 fseek(file,2,SEEK_SET);
 printf("%cn",fgetc(file));
 fseek(file,-2,SEEK_END);
 printf("%cn",fgetc(file));
 fclose(file);
 return 0;
}


?

List of Articles
번호 분류 제목 글쓴이 날짜 조회 수
공지 Tool/etc Programming 게시판 관련 2 MoA 2014.11.01 5344
188 Algorithm 2048게임 높은 점수 얻기 위한 알고리즘 MoA 2014.03.29 1282
187 Tool/etc UI Guidelines MoA 2014.03.11 1371
186 Tool/etc 자바스크립트 물리엔진 ㄷㄷ MoA 2014.03.10 1088
185 API/MFC 다이얼로그 기반에서 메뉴 내용이 갱신 안되는 문제 해결 MoA 2014.02.13 1522
184 Python 파이썬에서 C모듈 사용하기 MoA 2014.02.10 2550
183 Library CSpreadSheet MoA 2014.02.03 856
182 Reversing 워게임 사이트 정리 MoA 2014.01.27 1742
181 C/C++ RAND_MAX 2 MoA 2014.01.19 1190
180 Python OpenCV 이용한 템플릿 매칭 MoA 2014.01.16 2087
179 Tool/etc Quake 3 source code and review MoA 2014.01.15 943
178 Python 화면 캡쳐 소스 MoA 2014.01.14 1542
177 C/C++ __FILE__ __LINE__ __FUNCTION__ 등 매크로 MoA 2014.01.02 1515
176 Tool/etc 유용한 라이브러리 소개 MoA 2013.12.27 1615
175 Python Embedding Python in C/C++ MoA 2013.12.23 910
174 Python SciPy and NumPy MoA 2013.12.23 1181
173 API/MFC 다국어를 위한 StringTable, LoadString 1 MoA 2013.12.22 3294
172 API/MFC WTL 정리 file MoA 2013.12.22 1905
171 API/MFC GetLastInputInfo 함수 MoA 2013.12.06 988
170 Python [GUI] wxPython에서 에러메시지 콘솔로 보는 법 MoA 2013.12.03 1335
169 Python [GUI] wxPython 기본 프로그램 file MoA 2013.11.30 1426
Board Pagination Prev 1 2 3 4 5 6 7 8 9 10 ... 15 Next
/ 15