티스토리 뷰
파일과 스트림, 그리고 기본적인 파일의 입출력
fopen 함수호출을 통한 파일과의 스트림 형성과 FILE 구조체
#include <stdio.h>
FILE * fopen(const char * filename, const char * mode);
=> 성공 시 해당 파일의 FILE 구조체 변수의 주소 값, 실패 시 NULL 포인터 반환
FILE * fp = fopen("data.txt", "wt"); // 출력 스트림의 형성
FILE * fp = fopen("data.txt","rt"); // 입력 스트림의 형성
fopen(출력)write
#include <stdio.h>
int main(void)
{
FILE * fp=fopen("data.txt", "wt");
if(fp==NULL) {
puts("파일오픈 실패!");
return -1;
}
fputc('A', fp);
fputc('B', fp);
fputc('C', fp);
fclose(fp);
return 0;
}
fopen_s(출력)write
#include <stdio.h>
int main(void)
{
errno_t err;
FILE* fp;
err = fopen_s(&fp,"data.txt", "wt");
//err를 안쓰고 fopens~~를 쓰고 밑에 fp==NULL로 해도 돼
if (err != 0) {
puts("파일오픈 실패!");
return -1;
}
fputc('A', fp);
fputc('B', fp);
fputc('C', fp);
//fputs("asdfsdf",fp);
fclose(fp);
return 0;
}
#include <stdio.h>
int fclose(FILE * stream);
=> 성공 시 O, 실패 시 EOF를 반환
이렇게 fclose 함수의 호출을 통해서 개방되었던 파일을 닫아줘야 하는 이유는?
1. 운영체제가 할당한 자원의 반환
2. 버퍼링 되었던 데이터의 출력
스트림을 종료하지 않고 버퍼만 비우고 싶을 때에는 fflush 함수 호출(전에 나옴)(출력버퍼만 비워, 입력버퍼x)
#include <stdio.h>
int fflush(FILE * stream);
=> 함수호출 성공 시 O, 실패 시 EOF 반환
파일 스트림의 입력버퍼는 지울 필요 없어.
fopen(입력)read
#include <stdio.h>
int main(void)
{
int ch, i;
FILE * fp=fopen("data.txt", "rt");
if(fp==NULL) {
puts("파일오픈 실패!");
return -1;
}
for(i=0; i<3; i++)
{
ch=fgetc(fp);
printf("%c \n", ch);
}
fclose(fp);
return 0;
}
fopen_s(입력)read
#include <stdio.h>
int main(void)
{
int ch, i;
errno_t err;
FILE* fp;
err= fopen_s(&fp, "data.txt", "rt");
if (fp == NULL) {
puts("파일오픈 실패!");
return -1;
}
for (i = 0; i < 3; i++)
{
ch = fgetc(fp);
printf("%c \n", ch);
}
fclose(fp);
return 0;
}
파일의 개방 모드
스트림을 구분하는 기준1 : 일기 위한 스트림? 쓰기 위한 스트림?
데이터 READ 스트림 : 읽기만 가능
데이터 WRITE 스트림 : 쓰기만 가능
데이터 APPEND 스트림 : 쓰되 덧붙여 쓰기만 가능
데이터 READ/WRITE 스트림 : 읽기, 쓰기 모두 가능
그러나 C언어는 이를 바탕으로 6가지로 나눔
모드 | 스트림의 성격 | 파일이 없으면? |
r | 읽기 가능 | 에러 |
w | 쓰기 가능 | 생성 |
a | 파일의 끝에 덧붙여 쓰기 가능 | 생성 |
r+ | 읽기/쓰기 가능 | 에러 |
w+ | 읽기/쓰기 가능 | 생성 |
a+ | 읽기/덧붙여 쓰기 가능 | 생성 |
웬만하면 r, w, a 중에서 선택
스트림을 구분하는 기준2 : 텍스트 모드와 바이너리 모드
C언어에서는 개행이 \n 이지만 다른 데서는 아니야
형태 변환 어떻게 하지?? 파일을 텍스트 모드로 개방해
rt, wt, at, r+t, w+t, a+t
바이너리 모드로 개방할려면(변환 일어나면 안될때)
rb, wb, ab, r+b, w+b, a+b
파일 입출력 함수의 기본
fgets 함수의 호출을 통해서 읽어 드릴 문자열의 끝에는 반드시 \n 문자가 존재해야 한다.
feof 함수 기반의 파일복사 프로그램
#include <stdio.h>
int feof(FILE * stream);
=> 파일의 끝에 도달한 경우 0이 아닌 값 반환
#include <stdio.h>
int main(void)
{
FILE* src;
fopen_s(&src,"src.txt", "rt");
FILE* des;
fopen_s(&des,"des.txt", "wt");
int ch;
if (src == NULL || des == NULL) {
puts("파일오픈 실패!");
return -1;
}
while ((ch = fgetc(src)) != EOF)
fputc(ch, des);
if (feof(src) != 0)
puts("파일복사 완료!");
else
puts("파일복사 실패!");
fclose(src);
fclose(des);
return 0;
}
#include <stdio.h>
int main(void)
{
FILE* src;
fopen_s(&src,"src.txt", "rt");
FILE* des;
fopen_s(&des,"des.txt", "wt");
char str[20];
if (src == NULL || des == NULL) {
puts("파일오픈 실패!");
return -1;
}
while (fgets(str, sizeof(str), src) != NULL)
fputs(str, des);
if (feof(src) != 0)
puts("파일복사 완료!");
else
puts("파일복사 실패!");
fclose(src);
fclose(des);
return 0;
}
바이너리데이터의 입출력 : fread, fwrite
#include <stdio.h>
size_t fread(void * buffer, size_t size, size_t count, FILE * stream);
=> 성공 시 전달인자 count, 실패 또는 파일의 끝 도달 시 count보다 작은 값 반환
#include <stdio.h>
size_t fwrite(const void * buffer, size_t size, size_t count, FILE * stream);
=> 성공 시 전달인자 count, 실패 시 count보다 작은 값 반환
#include <stdio.h>
int main(void)
{
FILE* src;
fopen_s(&src,"suci.png", "rb");
FILE* des;
fopen_s(&des,"suci2.png", "wb");
char buf[20];
int readCnt;
if (src == NULL || des == NULL) {
puts("파일오픈 실패!");
return -1;
}
while (1)
{
readCnt = fread((void*)buf, 1, sizeof(buf), src);
if (readCnt < sizeof(buf))
{
if (feof(src) != 0)
{
fwrite((void*)buf, 1, readCnt, des);
puts("파일복사 완료");
break;
}
else
puts("파일복사 실패");
break;
}
fwrite((void*)buf, 1, sizeof(buf), des);
}
fclose(src);
fclose(des);
return 0;
}
'책 > 윤성우 열혈 C 프로그래밍' 카테고리의 다른 글
메모리 관리와 메모리의 동적 할당 (0) | 2020.09.24 |
---|---|
파일 입출력2 (0) | 2020.09.24 |
구조체와 사용자 정의 자료형2 (0) | 2020.09.21 |
구조체와 사용자 정의 자료형1 (0) | 2020.09.20 |
문자와 문자열 관련 함수 (0) | 2020.09.19 |