[열혈C프로그래밍] chapter 21. 파일 입출력

chapter 21

파일 입출력

#include <stdio.h>
FILE* fopen(const char* filename, const char* mode);
// 성공시 해당 파일의 FILE 구조체 변수의 주소값, 실패 시 NULL포인터 반환. 
#include <stdio.h>
int close(FILE* stream);

파일의 개방모드

모드 스트림의 성격 파일이 없으면?
r 읽기가능 에러
w 쓰기가능 생성
a 파일의 끝에 덧붙여 쓰기 가능 생성
r+ 읽기/쓰기 가능 에러
w+ 읽기/쓰기 가능 생성
a+ 읽기/덧붙여 쓰기 가능 생성

=> r모드는 읽기모드라 파일이 보존된채로 그대로 읽을수 있지만,

w 모드는 쓰기모드라 파일이 다시 초기화된후(백지) 쓰기가 된다는 것을 명심하자.

r+ 와 w+ 도 마찬가지이므로 보존된 채로 쓰고 읽고싶다면 r+을,

초기화시키고 읽고 쓰고 싶다면 w+을 쓰도록 한다.

텍스트 모드와 바이너리 모드
텍스트 형태의 파일 형식은 개방모드로 rt,wt,at,r+t,w+t,a+t(텍스트 모드)를 사용하면되고,
바이너리 형태의 파일 형식은 개방모드로 rb,wb,r+b,w+b,a+b(바이너리 모드)를 사용하면 된다.

덧붙여 각 os마다 개행문자의 형식이 다른데 (unix는 ‘\n’, windows는 ‘\r\n’, mac은 ‘\r’),
텍스트 모드를 사용하면 개행문자를 각 os에 맞게 변환해준다.

그리고 ‘r’이나 ‘b’를 사용하지않고 개방모드를 한다면 자연히 텍스트 모드로 개방된다.
따라서 바이너리 파일은 변환되면 안되기에 개방모드에 b를 반드시 붙여야 한다.

include

size_t fwrite(const void* buffer, size_t size, size_t count, FILE* stream); // 성공시 전달인자 count, 실패 시 count보다 작은 값 반환


* 서식에 따른 데이터 입출력: fprintf, fscanf


```c
# include <stdio.h>

int main(void){

  char name[10]="kimdo";
  char sex='M';
  int age=27;

  char name2[10];
  char sex2;
  int age2;

  FILE * fp = fopen("info.txt", "wt");

  fprintf(fp,"%s %c %d", name, sex, age);
  
  fclose(fp);

  fp = fopen("info.txt", "rt");

  fscanf(fp,"%s %c %d", name2, &sex2, &age2);
  
  printf("%s %c %d\n", name2,sex2,age2);  

  fclose(fp);

  return 0;
}

char name[20]; char sex; int age; }Friend;

int main(void){

FILE* fp; Friend f1; Friend f2;

//file write fp = fopen(“friend.bin”,”wb”); printf(“친구 정보 입력(name, sex, age)\n”); scanf(“%s %c %d” , f1.name, &f1.sex, &f1.age); fwrite((void*)&f1, sizeof(f1),1, fp);

fclose(fp); //스트림 삭제

//file read fp = fopen(“friend.bin”,”rb”); fread((void*)&f2, sizeof(f2),1, fp); printf(“%s %c %d \n”, f2.name, f2.sex, f2.age);

fclose(fp);

return 0; }


* 파일 위치 지시자의 이동: fseek

```c
# include <stdio.h>
int fseek(FILE* stream, long offset, int wherefrom);
// 성공 시 0, 실패 시 0이 아닌 값을 반환
매개변수 wherefrom 파일 위치 지시자
SEEK_SET 파일 맨 앞에서부터 이동을 시작
SEEK_CUR 현재 위치에서부터 이동을 시작
SEEK_SET 파일 맨 끝에서부터 이동을 시작

=> 파일을 동시에 읽고 쓰고 할때, 위치를 초기화하거나 옮겨야하는데 이때 많이 사용된다. 따라서 반드시 알고 가자

# include <stdio.h>
# include <stdlib.h>
# define true 1


int main(void){

  FILE * fp = fopen("simple.txt","w+");
  char * str1= (char*)malloc(sizeof(char)); 
  char * str2= (char*)malloc(sizeof(char)); 
   
  int opt;  
  int ch;

  while(true){
    printf("select option (1.read 2.write 3.quit)\n");
    printf(" : ");
    scanf("%d", &opt);  

  if (opt ==1){
    fseek(fp,0,SEEK_SET); // 파일위치를 처음으로 초기화. 그래야 처음부터 읽을 수 있다. 
  	while((ch=fgetc(fp))!=EOF)
      printf("%c",ch);
      
      printf("\n");
	}
  else if(opt ==2){

  	printf("write: ");
    scanf("%s",str2);
    fputs(str2,fp);
	}
	else
    break;
  }
  fclose(fp);

  return 0;
}