Chapter 17 파일 처리.

Slides:



Advertisements
Similar presentations
1/29 키보드로 직접 입력할 수 없는 다양한 기호와 한자를 입력하는 방법을 알아 보자. 또한 블록으로 영역을 설정하는 여러 가지 방법에 대해 살펴본 후 블록 으로 설정된 내용을 복사하여 붙여넣거나, 잘라내고 이동하는 방법에 대해서 도 알아보자. 02_ 문서의 입력과 편집.
Advertisements

Chapter 12. 배열. 배열  동일한 항목들이 동일한 크기로 연속적으로 메모리에 저장되는 구조  동일한 자료 유형이 여러 개 필요한 경우에 이용할 수 있는 자료 구조.
1 08 배열. 한국대학교 객체지향연구소 2 C 로 배우는 프로그래밍 기초 2 nd Edition 배열  동일한 자료유형의 여러 변수를 일괄 선언  연속적인 항목들이 동일한 크기로 메모리에 저장되는 구조  동일한 자료 유형이 여러 개 필요한 경우에 이용할 수 있는.
1. 2 차원 배열  배열은 동일한 데이터 유형으로 여러 개의 변수를 사용할 경우 같은 이 름으로 지정하여 간편하게 사용할 수 있도록 하는 것으로서 앞에서 1 차원 배열을 공부하였습니다.  2 차원 배열은 바둑판을 생각하면 되며, 1 차원 배열에서 사용하는 첨자를 2.
[ 단원 12 ] 파일처리 부산대학교 남 태 우.
ㅎㅎ 구조체 구조체 사용하기 함수 매개변수로서의 구조체 구조체 포인터와 레퍼런스 구조체 배열.
ㅎㅎ C++ 프로그래밍의 첫 걸음 C++로 프로그래밍한다는 것의 의미 세상에서 가장 간단한 C++ 프로그램
2장. 프로그램의 기본 구성. 2장. 프로그램의 기본 구성 2-1"Hello, World!" 들여다 보기 /* Hello.c */ #include int main(void) { printf("Hello, World! \n"); return 0;
컴퓨터프로그래밍 1주차실습자료 Visual Studio 2005 사용법 익히기.
쉽게 풀어쓴 C언어 Express 제16장 파일 입출력 C Express.
-Part3- 제3장 콘솔 입출력과 파일 입출력.
Chapter 10– 표준 함수(1) Outline 10.1 스트림과 파일 10.2 입출력 표준 함수
Chapter 7. 조건문.
제 9 장 구조체와 공용체.
컴퓨터 프로그래밍 기초 [Final] 기말고사
데이터 파일 C 데이터 파일과 스트림(Stream) 텍스트 파일 처리
조 병 규 Software Quality Lab. 한국교통대학교
윤성우의 열혈 C 프로그래밍 윤성우 저 열혈강의 C 프로그래밍 개정판 Chapter 12. 포인터의 이해.
쉽게 풀어쓴 C언어 Express 제16장 파일 입출력 C Express Slide 1 (of 23)
HW#1 Source 파일 제출 3.20(수)까지 제출 학번_이름_01.c
Part 14 파일 입출력 ©우균, 창병모 ©우균, 창병모.
제15장 파일 입출력 문자열을 출력하는 여러가지 방법 (15-2쪽) 문자열만 처리하는 입출력 함수
11장. 포인터 01_ 포인터의 기본 02_ 포인터와 Const.
8장 함수 함수의 필요성 라이브러리 함수와 사용자 정의 함수 함수의 정의, 원형, 호출 배열을 함수 인자로 전달 재귀호출.
SqlParameter 클래스 선문 비트 18기 발표자 : 박성한.
컴퓨터 프로그래밍 기초 #02 : printf(), scanf()
23장. 구조체와 사용자 정의 자료형 2.
11 표준 입출력과 파일 입출력 데이터를 읽고 쓰는 다양한 방법 익히기!.
6장. printf와 scanf 함수에 대한 고찰
14장. 포인터와 함수에 대한 이해.
11장. 1차원 배열.
10장 C 표준 파일 입출력 子曰 學而時習(실습?)之 不亦悅乎.
C 프로그래밍 C언어 (CSE2035) (Chap11. Derived types-enumerated, structure, and union) (1-1) Sungwook Kim Sogang University Seoul, Korea Tel:
사용자 함수 사용하기 함수 함수 정의 프로그램에서 특정한 기능을 수행하도록 만든 하나의 단위 작업
어서와 C언어는 처음이지 제14장.
3장 상수 변수 기본 자료형 키워드와 식별자 상수와 변수 기본 자료형 형변환 자료형의 재정의.
24장. 파일 입출력.
Chapter6 : JVM과 메모리 6.1 JVM의 구조와 메모리 모델 6.2 프로그램 실행과 메모리 6.3 객체생성과 메모리
3D 프린팅 프로그래밍 01 – 기본 명령어 강사: 김영준 목원대학교 겸임교수.
컴퓨터 프로그래밍 기초 - 10th : 포인터 및 구조체 -
컴퓨터 프로그래밍 기초 - 5th : 조건문(if, else if, else, switch-case) -
컴퓨터 프로그래밍 기초 - 8th : 함수와 변수 / 배열 -
5장 선택제어문 if 선택문 switch-case 선택문 다양한 프로그램 작성 조건 연산자.
Chapter 08. 함수.
문자열 컴퓨터시뮬레이션학과 2015년 봄학기 담당교수 : 이형원 E304호,
^^ Computer Programming 2 dmpr.cnu.ac.kr/~daygax.
함수(Function) ◈ 함수의 개념 및 사용 이유 ◈ 함수 정의, 호출 및 선언 ◈ 지역변수와 전역변수 ◈ return 문
디버깅 관련 옵션 실습해보기 발표 : 2008년 5월 19일 2분반 정 훈 승
제 15 강 문자와 코드 shcho.pe.kr.
Homework #12 (1/2) 프로그램을 작성하고, 프로그램과 실행 결과를 프린트하여 제출한다.
Linux 9.X 기초에서 활용까지 Chapter 06 VI 편집기.
Chapter 10 데이터 검색1.
함수, 모듈.
TVM ver 최종보고서
구조체(struct)와 공용체(union)
실습과제 1번 생성된 파일 basic.txt를 프로젝트 폴더에서 메모장으로 열고 내용을 확인
Chapter 12 파일 입출력.
실습과제 (변수와 자료형, ) 1. 다음 작업 (가), (나), (다)를 수행하는 프로그램 작성
동적메모리와 연결 리스트 컴퓨터시뮬레이션학과 2016년 봄학기 담당교수 : 이형원 E304호,
1장 C 언어의 개요 C 언어의 역사와 기원 C 언어의 특징 프로그램 과정 C 프로그램 구조 C 프로그램 예제.
제 29 강 스트링(string) 다루기 s a i s . s T i h t g r i n.
C 13장. 입출력 라이브러리 #include <stdio.h> int main(void) { int num;
어서와 C언어는 처음이지 제21장.
개정판 누구나 즐기는 C언어 콘서트 제13장 동적 메모리 출처: pixabay.
2019 1학기 응용프로그래밍 - 파일 처리 01 파일 열기 02 파일 저장과 내용 읽기 03 이진파일 처리 04 임의접근 파일 처리 05 파일 관련 함수들.
7 생성자 함수.
6 객체.
SPL-Duino 블록 편집기 이용하기 전류센서 블록 만들기 SPL-Duino 블록 편집기를 실행합니다.
제 10 강 문자 입출력.
2019 2학기 9장 배열과 포인터 1. 주소, 주소연산자(&) 2. 포인터, 역참조연산자(*) 3. 배열과 포인터.
Presentation transcript:

Chapter 17 파일 처리

함수 fopen() 파일을 만들기 위해서는 함수 fopen()을 이용 함수 fopen()의 함수 원형은 다음과 같으며 헤더 파일 stdio.h 파일에 정의 함수 fopen()에서 f는 파일(file)의 f를 의미 함수 fopen()은 두 개의 문자열 전달인자를 이용, 반환 값은 포인터 값인 FILE * 반환 값의 유형인 FILE *에서 FILE은 헤더 파일 stdio.h 파일에 정의되어 있는 구조체 유형, 그러므로 반환 값의 유형 FILE *은 구조체 FILE의 포인터 유형 struct _iobuf { char *_ptr; int _cnt; char *_base; int _flag; int _file; int _charbuf; int _bufsiz; char *_tmpfname; }; typedef struct _iobuf FILE;

파일 열기 함수 fopen()에서 첫 번째 문자열은 처리하려는 파일 이름이고, 두 번째 문자열은 파일 처리 종류(모드) 다음 소스는 파일 “basic.txt”을 여는 모듈로서, 파일에 자료를 쓰기 위해 파일을 열므로 모드 값을 “w”로 기술 함수 fopen()은 성공적으로 파일을 열면(open), FILE 포인터를 반환하므로 그 값을 변수 f에 저장 함수 fopen()은 파일을 여는데 실패하면 NULL 값을 반환 조건문 if를 위와 같이 함수 fopen()과 함께 이용하면 파일 열기에 실패할 경우 문장 "파일이 열리지 않습니다.\n"을 출력 파일 처리가 모두 끝났으면 파일 포인터 f를 인자로 함수 fclose(f)를 호출하여 반드시 파일을 닫도록 함수 fopen()의 두 번째 인자는 파일 처리 종류(모드) “r”, “w”, “a”, “r+”, “w+”, “a+”의 종류 FILE *f; char fname[] = "basic.txt"; if ((f = fopen(fname, "w")) == NULL) { printf( "파일이 열리지 않습니다.\n" ); }; … fclose(f);

파일 처리 모드 파일 처리 모드 종류 의미 모드 의미 r 읽기(read) 모드로 파일을 연다. 파일이 없으면 에러가 발생한다. w 쓰기(write) 모드로 파일을 연다. 파일이 없으면 새로 만들고, 기존의 파일이 있으면 그 이전의 내용은 없어지고 파일의 처음부터 쓴다. 이 모드로는 파일 내용을 읽을 수 없다. a 추가 쓰기(append) 모드로 파일을 연다. 파일이 없으면 새로 만들고, 기존의 파일이 있으면 그 파일의 가장 뒤부터 파일에 추가한다. r+ 읽기(read)와 쓰기(write) 모드로 파일을 연다. 파일이 없으면 에러가 발생한다. w+ 읽기와 쓰기(write) 모드로 파일을 연다. 파일이 없으면 새로 만들고, 기존의 파일이 있으면 그 이전의 내용은 없어지고 파일의 처음부터 쓴다. a+ 추가 쓰기(append) 모드로 파일을 연다. 파일이 없으면 새로 만들고, 기존의 파일이 있으면 그 파일의 가장 뒤부터 파일에 추가한다. 파일의 어느 곳이나 읽기는 가능하나 쓰기는 추가적으로만 가능하다.

파일에 글자 쓰기 함수 fprintf() 함수 fopen()을 이용하여 쓰기 모드로 파일을 연 다음, 원하는 자료를 파일에 써 보자. C 언어는 파일에 자료를 쓰는 함수로 fprintf()를 제공 함수 fprintf()는 함수 printf()와 유사하며, 첫 인자로 출력하려는 목적지인 파일을 지정 위 문장은 파일 f에 문자열 "이름이 %s인 학생의 성적은 %d 입니다.\n"을 쓰는 구문 위 구문으로 변수 name과 point에 저장된 문자열과 정수 값이 적절히 연결된 문자열이 파일에 기록 fprintf(f, "이름이 %s인 학생의 성적은 %d 입니다.\n", name, point);

예제 소스 Filebasic.c 함수 fopen(), fprintf()를 이용하여 표준입력으로 받은 이름과 점수를 파일 “basic.txt”에 출력하는 프로그램 파일이 쓰기 모드로 열리지 않으면 함수 exit()를 이용하여 프로그램을 종료 함수 exit()를 이용하려면 헤더 파일 stdlib.h를 포함 함수 exit()는 함수를 강제로 종료하는 기능을 수행하며, 인자로 정수 값을 쓰는데, 0은 정상적인 종료를 의미하고, 0이 아닌 값은 정상적인 종료가 아님을 운영체제에게 알리는 의미로 사용 if ((f = fopen(fname, "w")) == NULL) { printf( "파일이 열리지 않습니다.\n" ); exit(1); };

소스와 결과

함수 fprint, fscanf int fprintf(FILE *, const char *, ...); 파일에 자료를 쓰거나 읽기 위하여 함수 fprintf()와 fscanf()를 이용 이 함수를 이용하기 위해서는 헤더 파일 stdio.h 파일을 포함 함수 fprintf()와 fscanf()의 함수 원형 위 함수의 첫 번째 인자는 입출력에 이용될 파일이고, 두 번째 인자는 입출력되는 문자열이며, 다음 인자들은 입출력될 변수 목록 함수 원형에서 기호 …은 여러 인자가 계속됨을 의미 함수 fprintf()와 fscanf()를 표준 입출력에도 이용 가능 즉 함수 fprintf()와 fscanf()의 첫 번째 인자에 각각 stdin 또는 stdout를 이용하면 표준 입력, 표준 출력으로 이용이 가능 기호 상수 stdin, stdout은 stderr과 함께 헤더 파일 stdio.h에 정의되어 있는 값으로 각각 표준입력, 표준출력, 표준에러를 의미 int fprintf(FILE *, const char *, ...); int fscanf(FILE *, const char *, ...); 표준 파일 키워드 장치(device) 표준입력 stdin 키보드 표준출력 stdout 모니터 화면 표준에러 stderr #define stdin (&_iob[0]) #define stdout (&_iob[1]) #define stderr (&_iob[2])

예제 소스 파일 내용 쓰기, 읽기를 처리하는 프로그램 if ((f = fopen(fname, "w")) == NULL) { 쓰기 모드로 파일을 열어 표준입력으로 받은 이름과 중간 기말점수를 파일에 기록하고 파일을 닫은 후, 다시 읽기 모드로 그 파일을 열어 기록된 내용을 파일에서 읽어와 표준출력으로 출력하는 프로그램 쓰기 모드로 파일을 열어 표준 입력으로 이름, 중간점수, 기말점수를 받는 모듈 표준입력의 이름을 빈칸으로 구분하므로 빈칸이 없는 이름을 입력해야 함 if ((f = fopen(fname, "w")) == NULL) { printf( "파일이 열리지 않습니다.\n" ); exit(1); }; printf("이름과 성적(중간, 기말)을 입력하세요.\n" ); scanf("%s%d%d", name, &point1, &point2);

구현 다음은 표준 입력으로 읽어들인 이름, 중간점수, 기말점수를 함수 fprintf()를 이용하여 파일 f에 출력하는 모듈 변수 cnt는 이름 앞에 번호를 붙이려는 목적으로 이용 다음은 위에서 자료를 쓴 파일의 내용을 다시 읽으려는 소스 파일을 읽기 모드로 열므로 모드 인자는 “r”로 지정 //파일 "grade.txt"에 쓰기 fprintf(f, "%d %s %d %d\n", ++cnt, name, point1, point2);   fclose(f); if ((f = fopen(fname, "r")) == NULL) { printf( "파일이 열리지 않습니다.\n" ); exit(1); };   //파일 "grade.txt"에서 읽기 fscanf(f, "%d %s %d %d\n", &cnt, name, &point1, &point2);

구현 위에서 함수 fscanf()를 이용하여 파일에서 적당한 내용을 읽은 후, 다시 함수 fprintf()를 이용하여 표준출력으로 출력 파일에서 함수 fscanf()를 이용하려면 파일의 내부 자료의 저장 형태를 알아야 정확히 읽을 수 있음 출력은 먼저 머리 부분으로 제목을 출력하고 다음에 내용을 출력 함수 fprintf()는 첫 인자를 stdout으로 지정하여 표준출력으로 이용 다음과 같이 함수 printf()를 이용도 가능 //표준출력에 쓰기 fprintf(stdout, "\n%6s%18s%8s%8s\n", "번호", "이름", "중간", "기말"); fprintf(stdout, "%6d%18s%8d%8d\n", cnt, name, point1, point2); fclose(f); printf("%6d%18s%8d%8d\n", cnt, name, point1, point2);

예제 소스 Filewrite.c 파일 내용 쓰기, 읽기를 처리하는 프로그램 프로그램 실행이 성공적으로 종료되면 파일 grade.txt 파일이 생성

함수 fgets()와 fputs() 함수 fgets()와 fputs() 함수 fgets() 인자 함수 fputs() 인자 이 함수도 헤더파일 stdio.h 파일에 다음과 같은 함수원형으로 정의 함수 fgets()는 문자열을 개행문자(\n)까지 읽어 개행문자도 함께 입력 문자열에 저장 마찬가지로 함수 fputs()는 문자열을 그대로 출력 함수 fgets() 인자 첫 번째 인자는 문자열이 저장될 문자 포인터이고, 두 번째 인자는 입력할 문자의 최대 수이며, 세 번째 인자는 입력 문자열이 저장될 파일 함수 fputs() 인자 첫 번째 인자는 출력될 문자열이 저장된 문자 포인터이고, 두 번째 인자는 문자열이 출력되는 파일 char * fgets(char *, int, FILE *); int fputs(char *, FILE *);

함수 fgetc()와 fputc() 문자 하나를 파일에 입출력하는 함수로 fgetc()와 fputc()를 제공 이 함수의 원형은 헤더파일 stdio.h에 정의 이 함수들은 문자 하나의 입출력의 대상인 파일 포인터를 인자로 이용 이 함수와 같은 함수로 getc()와 putc()도 이용 가능 문자의 표준 입출력에 이용되는 getchar()와 putchar()는 다음과 같이 함수 getc()와 putc()를 이용한 매크로 함수 fgetc()와 fputc()는 getc()와 putc()와 그 기능은 동일하며, fgetc()와 fputc()는 함수이고, getc()와 putc()는 매크로 int fgetc(FILE *); int fputc(int, FILE *); int getc(FILE *); int putc(int, FILE *); #define getchar() getc(stdin) #define putchar(_c) putc((_c),stdout)

함수 feof()와 ferror() 함수 feof() 함수 ferror() 이 함수는 헤더파일 stdio.h에 다음 함수 원형으로 정의 파일의 위치가 파일의 마지막(end of file)인지를 검사하여, 파일의 마지막이면 0이 아닌 값을, 파일의 마지막이 아니면 0을 반환 그러므로 표준입력에서 계속적으로 입력을 받는 구문으로 다음을 이용 가능 함수 ferror() 파일 처리에서 오류가 발생했는지 검사하는 함수 함수의 원형은 헤더파일 stdio.h에 정의 이전 파일 처리에서 오류가 발생하면 0이 아닌 값을 발생하고, 오류가 발생하지 않으면 0을 반환 int feof(FILE *); while (!feof(stdin)) { … } int ferror(FILE *);

예제 소스 목적 함수 fgets()와 fputs()를 이용하여 표준입력으로 여러 줄을 입력 받아 여러 줄을 지정된 파일에 출력하는 프로그램을 작성 구현 주요 변수 표준입력으로 입력된 한 줄의 자료를 함수 fgets()를 이용하여 입력 받고, 바로 이 한 줄의 문자열을 함수 fputs()를 이용하여 파일 f에 저장하는 모듈 char fname[] = "grade.txt"; char names[80]; FILE *f; printf("이름과 성적(중간, 기말)을 입력하세요.\n" ); fgets(names, 80, stdin); while (!feof(stdin)) { //파일 "grade.txt"에 쓰기 fprintf(f, "%d ", ++cnt); fputs(names, f); } fclose(f);

구현 파일의 내용을 파일의 끝까지 한 줄 한 줄 출력하는 모듈 파일의 내용을 출력하기 전에 함수 printhead()를 호출하여 제목을 출력 파일 포인터 f를 이용하여 함수 feof()을 이용하며, 파일 내용의 형태를 알고 있으므로 함수 fscanf()를 이용하여 각 자료형으로 자료를 입력 입력 받은 자료는 함수 fprintf()를 이용하여 적절한 형태로 출력 파일을 함수 fopen()을 이용하여 열었으면, 잊지 말고 함수 fclose()를 이용하여 닫는 프로그래밍 습관을 기르도록 printhead(); while (!feof(f)) { //파일 "grade.txt"에서 읽기 fscanf(f, "%d %s %d %d\n", &cnt, names, &point1, &point2); //표준출력에 쓰기 fprintf(stdout, "%6d%18s%8d%8d\n", cnt, names, point1, point2); }

소스와 결과

예제 소스 목적 조건 도스 명령어 type와 같은 프로그램을 만들어보자. 이 프로그램은 프로그램 이름을 list로 하여 “list filename”을 입력하면 파일 filename의 내용을 표준출력으로 출력하는 프로그램 조건 명령어 줄 인자를 활용, 두 번째 인자가 파일이름에 해당 이 파일이름에 해당하는 인자를 기술하지 않으면 간단한 사용법을 알리고 프로그램은 종료 파일 내용의 출력은 한 줄마다 맨 앞에 줄 번호를 출력 첫 실행에서는 파일이름을 입력하지 않았고, 두 번째에는 이 프로그램의 소스를 파일이름으로 기술

구현 명령어 줄 인자가 2개가 아니면 사용법을 출력하고 종료 명령어 줄 인자에서 두 번째 인자인 argv[1]을 가지고 파일 열기 파일을 여는데 문제가 있으면 프로그램을 종료 if (argc != 2) { printf("사용법 : list filename\n" ); exit(1); }; if ((f = fopen(argv[1], "r")) == NULL) { printf( "파일이 열리지 않습니다.\n" ); exit(1); };

구현 처음 줄에 줄 번호를 출력하고, fgetc(f)를 이용하여 파일 f에 문자를 하나 하나 읽어, 그 읽은 문자 ch를 putchar(ch)를 이용하여 표준출력으로 출력 아래 소스의 putchar(ch)는 putc(ch, stdout)로도 가능 출력된 문자가 개행문자이면 새로운 줄이 시작되므로 줄 번호를 출력 이러한 정수를 출력하는 부분에서는 함수 printf()를 이용 프로그램의 마지막에는 잊지 말고 파일을 닫음 printf("%4d: ", ++cnt); while ((ch = fgetc(f)) != EOF) { putchar(ch); if (ch == '\n') { }; } printf("\n"); fclose(f);

예제 소스 List.c 이 프로그램은 프로그램 이름을 list로 하여 “list filename”을 입력하면 파일 filename의 내용을 표준출력으로 출력하는 프로그램

텍스트 파일과 이진 파일 텍스트 파일 이진 파일 함수 fprintf()와 fscanf()는 자료의 입출력을 텍스트 모드로 처리 텍스트 파일은 텍스트 편집기(에디터)로 그 내용을 알 수 있으며, 텍스트 파일의 내용은 모두 지정된 문자 코드(일반적으로 아스키 코드) 값을 갖고 있어, 그 내용을 확인할 수 있을 뿐만 아니라 인쇄가 가능 함수 fprintf()를 이용하여 정수형 변수 cnt에 저장된 값을 파일 f에 출력하는 과정 함수 fprintf()를 이용하여 실제 정수 int형 변수 cnt를 출력하면, 실제적으로 파일에 저장되는 자료는 정수 값인 10에 해당하는 각 문자의 아스키 값을 저장 그러므로 함수 fprintf()를 이용하여 출력하면, 파일 f에는 정수 값 10에 해당하는 각각의 문자 ‘1’과 ‘0’의 아스키 코드 값이 저장 이진 파일 이러한 텍스트 파일과는 다르게 이진(binary) 파일은 C 언어의 자료형을 모두 유지하면서 바이트 단위로 저장하는 파일 이진 파일의 대표적인 예가 실행파일, 이러한 이진 파일은 일반 편집기로는 그 내용 확인 불가능

함수 fwrite와 fread 이진 파일 처리 인자와 반환 값 void * 이와는 다르게 이진(binary) 모드로 입출력을 처리하려면 함수 fwrite()와 fread()를 이용 함수 fwrite()는 헤더파일 stdio.h에 다음과 같은 함수원형으로 정의 이진 파일에 저장되어 있는 자료형을 입력하는 함수 fread() 각각의 인자는 출력 함수 fwrite()와 동일 인자와 반환 값 인자 첫 번째 인자는 출력될 자료의 주소 값이며, 두 번째 인자는 출력될 자료의 바이트 크기이고, 세 번째 인자는 출력될 단위 자료의 묶음 개수이고, 마지막 인자는 출력될 파일 포인터 반환값 값은 파일에 출력된 단위 자료형의 개수 void * 위에서 첫 번째 인자의 자료형이 void *로 모든 자료형의 포인터를 대신할 수 있는 포인터 변수 size_t fwrite(const void *, size_t, size_t, FILE *); size_t fread(void *, size_t, size_t, FILE *);

이진 파일 입출력 이해 함수 fwrite()를 이용하여 정수형 변수 cnt 값을 파일 f에 출력하는 과정  이진 파일 입출력 이해 함수 fwrite()를 이용하여 정수형 변수 cnt 값을 파일 f에 출력하는 과정 함수 fwrite()는 바이트 단위로 원하는 블록을 파일에 출력하기 위한 함수 함수 fwrite()에 의하여 출력된 자료는 함수 fread()를 이용하여 입력해야 그 자료유형 유지가 가능

예제 소스 Scorefile.c 학생의 성적정보를 다음과 같이 구조체로 표현하고, 표준입력으로 여러 명의 자료를 입력 받아 구조체 자료형에 저장하여 파일 “score.bin”에 저장하는 프로그램을 작성 구조체 personscore는 번호, 이름, 중간, 기말, 퀴즈 점수를 멤버로 가지며 이에 대한 정의는 헤더파일 score.h로

구현 이 구조체 자료형으로 한 학생의 정보를 저장하기 위하여, 표준입력으로 번호를 제외한 이름, 중간, 기말, 퀴즈 점수를 입력 표준입력은 사람마다 한 행씩 받으며, 입력된 학생 수로 학생 번호를 입력 표준입력은 한 행마다 fgets()를 이용하여 하나의 문자열로 받고, 이 입력된 문자열에서 각 구조체의 멤버 자료를 추출 문자열에서 자료를 추출하기 위하여 함수 sscanf()를 이용 함수 sscanf()는 문자열로부터 자료를 입력 받는 함수 printf("이름과 성적(중간, 기말, 퀴즈)을 입력하세요.\n" ); fgets(line, 80, stdin); while (!feof(stdin)) { //표준입력의 한줄을 구조체의 멤버 별로 자료를 입력 sscanf(line, "%s %d %d %d", score.name, &score.mid, &score.final, &score.quiz); score.number = ++cnt; fwrite(&score, sizeof(pscore), 1, f); }

예제 소스 Readscorefile.c 이전에 만들었던 이진 파일 score.bin 파일의 내용을 읽어 표준 출력으로 출력하는 프로그램 이전의 헤더파일 score.h 파일은 그대로 이용하고, 출력 형태는 다음과 같은 결과

구현 이진 파일을 읽기 위하여 읽기 모드 “r”로 파일 열기 이진 자료를 읽기 위하여 함수 fread()를 이용 함수 fread()에서 첫 인자는 읽은 자료를 저장할 구조체 변수 score의 주소 값을 기술 함수 feof()을 이용하여 파일의 마지막까지 구조체 자료를 읽어 적당한 출력 형태가 되도록 함수 fprintf()를 이용하여 출력 if ((f = fopen(fname, "r")) == NULL) { printf( "파일이 열리지 않습니다.\n" ); exit(1); }; fread(&score, sizeof(pscore), 1, f); while (!feof(f)) { //표준출력에 쓰기 fprintf(stdout, "%6d%18s%8d%8d%8d\n", score.number, score.name, score.mid, score.final, score.quiz); }

파일 내부 위치 파일 위치 포인터 순차적, 임의 접근 파일을 열면 항상 파일 위치 포인터(file pointer)라는 것이 파일의 한 장소를 가리킴 여기에서의 파일 위치 포인터는 변수에서의 파일 포인터와는 다른 것으로 파일 내부를 바이트 단위로 파일 내부 위치를 나타내는 값 파일 포인터가 100L이라면 파일의 처음에서부터 100바이트 떨어진 위치에 현재 파일 포인터가 위치 파일 포인터 값은 일반적으로 자료형 long으로 취급하므로 상수를 기술할 때 100L처럼 수 뒤에 L을 기술 가능 파일 포인터는 파일 내부에서 자료를 읽거나 쓰는 만큼 파일의 현재 위치에서 뒤로 이동 순차적, 임의 접근 파일에서 원하는 장소로 자유롭게 이동하는 것을 임의 접근(Random Access) 파일의 임의 접근을 처리하기 위해서는 파일 포인터를 자유 자재로 이동하는 함수 fseek()이 필요

함수 fseek() fseek() offset 함수 fseek()는 함수 원형이 헤더파일 stdio.h 파일에 정의 함수 fseek()는 파일 fptr에서 기준점 mode에서 offset만큼 떨어진 곳으로 파일 포인터를 위치하는 함수 offset 함수 fseek()에서 두 번째 인자는 long 유형으로 기준점으로부터 떨어진 값을 말하며 흔히 오프셋(offset)이라 함 함수 fseek()에서 세 번째 인자는 정수형 기호 상수로 다음 세 가지 중의 하나를 이용 int fseek(FILE *fptr, long offset, int mode) 기호 값 의미 SEEK_SET 파일의 시작 위치 SEEK_CUR 1 파일의 현재 위치 SEEK_END 2 파일의 끝 위치

기준 세가지 함수 fseek(f, 100L, SEEK_SET)의 호출은 파일 포인터를 파일의 처음 위치에서 100바이트 떨어진 위치로 이동시킨다. 함수 fseek(f, 100L, SEEK_CUR)의 호출은 파일 포인터를 파일의 현재 위치에서 100바이트 떨어진 위치로 이동시킨다. 함수 fseek(f, -100L, SEEK_END)의 호출은 파일 포인터를 파일 끝 위치에서 앞으로 100바이트 떨어진 위치로 이동시킨다.

int fseek(FILE *, long, int) 파일 관련 여러 함수 함수 fseek()에서 두 번째 인자는 세 번째 인자인 기준점으로부터 떨어진 값을 말하며, 양수는 뒤, 음수는 앞으로 방향을 지시 파일 포인터와 관련된 함수로서 다음 세 가지 함수를 이용 함수 ftell()은 인자인 파일의 파일 포인터를 반환하며 함수 rewind()는 파일 포인터를 무조건 제일 앞으로 이동 함수 기능 int fseek(FILE *, long, int) 파일 포인터를 세 기준점으로부터 오프셋만큼 이동하는 함수 long ftell(FILE *) 파일의 현재 파일 포인터를 반환하는 함수 void rewind(FILE *) 파일의 현재 포인터를 0 위치(파일의 시작점)로 이동하는 함수

예제 소스 Appendscore.c 바로 이전에 작성한 readscorefile.c 프로그램을 발전시켜 더 많은 학생의 성적정보를 추가하는 프로그램을 작성 프로그램이 실행되면 제일 먼저 파일 score.bin 파일에 있는 학생 정보를 모두 읽어와 출력 파일에 있는 마지막 학생 정보로부터 마지막 학생 번호를 알아냄 이 번호에 1씩 증가시키면서 다음에 추가될 학생의 번호로 이용 추가되는 자료는 이전의 학생정보를 입력하는 방식과 동일하게 한 줄에 한 명의 학생 정보를 입력

구현 추가될 학생 정보는 위와 같이 학생마다 한 행씩 자료를 받아서 파일 score.bin 파일에 저장 키 ctrl + z를 누르면 입력이 종료되고, 다시 파일 score.bin에서 모든 자료를 읽어 모든 정보를 출력 프로그램에서 제일 먼저 자료를 추가할 score.bin 파일을 모드 “a+”로 연다. 파일을 “a+”로 여는 이유는 학생 정보를 추가도 하고, 다시 읽기도 하기 위함 이 프로그램에서는 파일 score.bin을 한번 열고, 프로그램 종료 시에 닫도록 파일에 저장된 정보를 출력하기 위해 함수 printscore()를 만들어 호출한다. if ((f = fopen(fname, "a+")) == NULL) { printf( "파일이 열리지 않습니다.\n" ); exit(1); }; printscore(f);

구현 모든 정보를 출력하면 파일 포인터는 파일 끝에 위치 학생 정보의 마지막 자료를 구조체 변수 score에 저장하기 위하여 함수 fseek()을 다음과 같이 이용 다음에는 학생정보를 추가하는 함수 appendscore()를 호출하고 이어서 다시 모든 자료를 출력하는 함수 printscore()를 호출하고 파일을 닫음 offset = (long) sizeof(pscore); fseek(f, -offset, SEEK_CUR); fread(&score, sizeof(pscore), 1, f);   //제일 마지막 자료의 번호를 찾기위하여 cnt = score.number; printf("\n제일 마지막 번호가 %d번 입니다. \n\n", cnt); fseek(f, 0L, SEEK_END); appendscore(f, cnt);   printscore(f); fclose(f);

구현 함수 printscore()에서는 읽을 파일을 인자로 처리하고, 파일을 처음부터 읽어야 하므로 함수 rewind()를 호출하여 파일 포인터를 0으로 지정 void printscore(FILE *f) { pscore score;   rewind(f); printhead(); fread(&score, sizeof(pscore), 1, f); while (!feof(f)) { … }

입출력 함수 여러 입출력 함수

파일 삭제, 이름 바꾸기 함수 remove() 함수 rename() 지정된 특정한 파일을 삭제하고 함수 remove()는 remove(“sample.txt”)와 같이 문자열로 지정된 파일을 삭제 함수 rename() 지정된 파일의 이름을 새로운 이름으로 바꾸는 역할을 수행 함수 rename()은 rename(“oldname.txt”, “newname.txt”)과 같이 앞의 파일이름을 뒤 파일이름으로 바꾸는 역할 함수 remove()와 rename()도 헤더 파일 stdio.h에 그 함수 원형이 정의 기능 함수 원형 파일 삭제 int remove(const char *) 파일 이름 바꾸기 int rename(const char *, const char *)

예제 소스 filepro.c 이 프로그램은 옵션과 파일이름을 명령어 줄 인자로 처리하는 프로그램으로 옵션에 따라 다음과 같은 기능을 수행하도록 프로그램 첫 번째 옵션은 다음과 같이 –c로 인자인 파일이름으로 파일을 생성하는 기능을 수행 이 파일 filename은 기존에 없으면 새로 생성하고, 만일 있으면 있는 파일을 이용 파일에는 이 명령어를 수행한 횟수를 함수 getw()를 이용하여 파일에 저장하는 기능을 수행 >fileproc –c filename 두 번째 옵션은 –d를 이용하며 지정된 파일 filename을 삭제한다. >fileproc –d filename   세 번째 옵션은 –n를 이용하며 지정된 파일 filename1을 새로운 이름 filename2으로 수정 >fileproc –n filename1 filename2

결과 다음은 이 프로그램을 명령어 프롬프트에서 실행한 결과 이 프로그램에서 옵션 –d는 함수 remove()를 이용하여 삭제하고, 옵션 –n은 함수 rename()을 이용하여 파일이름을 수정

구현 위 프로그램에서 옵션 –c는 지정된 파일에 옵션 –c를 실행한 횟수를 출력 이를 위하여 실행 시에 파일에서 이전에 저장한 정수를 getw() 함수로 읽어와 1을 더하여 함수 putw()를 이용하여 다시 그 파일에 저장 파일이 없는 경우에는 새로이 파일을 만들어서 1을 저장 명령어 줄 인자에서 옵션에 저장된 문자열은 argv[1] 다음 소스와 같이 옵션에 따라 변수 mode에 적당한 값을 저장 if (strcmp(argv[1], "-c") == 0) { mode = 1; } else if (strcmp(argv[1], "-d") == 0) { mode = 2; } else if (strcmp(argv[1], "-n") == 0) { mode = 3; };

구현 다음은 옵션이 –c인 경우 이전에 파일이 있으면, 모드 “r+”로 파일을 열고, 이전에 파일이 없으면 모드 “w+”로 파일을 여는 모듈 switch (mode) { case 1: if ((f = fopen(argv[2], "r+")) == NULL) { if ((f = fopen(argv[2], "w+")) == NULL) { printf( "파일이 열리지 않습니다.\n" ); exit(1); } }; …

구현 다음 소스는 이전에 사용한 파일은 파일 크기가 0이 아니므로, 그 파일에서 맨 앞의 정수 하나를 함수 getw()를 이용하여 읽어오는 모듈 다음은 변수 cnt에는 이전의 횟수가 저장되어 있으므로 1을 더한 ++cnt를 파일의 맨 앞 부분에 함수 putw()를 이용하여 다시 출력 fseek(f, 0L, SEEK_END); if (ftell(f) != 0) { fseek(f, 0L, SEEK_SET); cnt = getw(f); } fseek(f, 0L, SEEK_SET); putw(++cnt, f); printf("-c 옵션을 파일 %s에 %d번 사용했습니다.\n", argv[2], cnt); fclose(f); break;

구현 다음은 옵션이 –d인 경우 다음은 옵션이 -n인 경우 remove(argv[2]) 함수를 호출하여 파일을 삭제 rename(argv[2], argv[3]) 함수를 호출하여 파일이름을 수정 case 2: remove(argv[2]); break; case 3: if (argc != 4) { printf("사용법 : -[c,d,n] filename\n" ); exit(1); }; rename(argv[2], argv[3]); break;

예제 소스

프로그램 연습 프로그램 목적 이 장에서 배운 함수들을 이용하여 score.bin 파일에서 학생 번호를 이용하여 학생 정보를 검색하는 프로그램을 작성 헤더 파일 score.h를 그대로 이용하고, 함수 printscore()와 printhead()를 그대로 이용하며, 함수 searchscore()를 만들어 검색에 이용  프로그램은 다음 조건을 만족하도록 제일 먼저 score.bin 파일에 있는 모든 정보를 출력하자. 가장 큰 학생 번호를 출력하여 잘못된 학생번호를 입력하지 않도록 한다. 검색할 학생번호를 입력 받는다. 검색 함수 searchscore(FILE *f, int cnt)는 두 개의 인자를 가지며, 두 번째 인자가 검색할 학생 번호이다. 검색 결과를 출력한다.

결과 실행 결과

구현 구조체가 여러 개 저장되어 있는 파일에서, 파일의 전체 크기를 구조체 하나의 크기로 나누면 총 구조체의 수를 알 수 있음 파일의 전체 크기는 파일 포인터를 파일 가장 끝으로 보내고 함수 ftell()을 이용하면 알 수 있음 fseek(f, 0L, SEEK_END); max = ftell(f) / sizeof(pscore); printf("\n가장 큰 학생 번호는 %d번 입니다. >>\n", max); printf("찾을 학생 번호를 입력하세요. >> "); scanf("%d", &cnt);   if (1 <= cnt && cnt <= max) searchscore(f, cnt); else printf("번호를 잘못 입력했습니다.\n"); fclose(f);

구현 파일에서 cnt 번째의 구조체를 읽어야 하므로 파일 포인터를 파일의 처음(SEEK_SET)에서부터 sizeof(pscore) * (cnt-1) 바이트만큼 이동 이를 함수 fseek()을 이용하여 이동하고, 함수 fread()로 구조체 하나를 이진 자료로 읽어 들임 void searchscore(FILE *f, int cnt) { pscore score;   long offset = (long) (sizeof(pscore) * (cnt-1)); fseek(f, offset, SEEK_SET); fread(&score, sizeof(pscore), 1, f); printf("\n찾은 학생 정보는 >>\n\n"); fprintf(stdout, "%6s%18s%8s%8s%8s\n", "번호", "이름", "중간", "기말", "퀴즈"); fprintf(stdout, "%6d%18s%8d%8d%8d\n", score.number, score.name, score.mid, score.final, score.quiz); }

소스와 결과