쉽게 풀어쓴 C언어 Express 제16장 스트림과 파일 입출력 C Express.

Slides:



Advertisements
Similar presentations
Chapter 12. 배열. 배열  동일한 항목들이 동일한 크기로 연속적으로 메모리에 저장되는 구조  동일한 자료 유형이 여러 개 필요한 경우에 이용할 수 있는 자료 구조.
Advertisements

6 장. printf 와 scanf 함수에 대한 고찰 printf 함수 이야기 printf 는 문자열을 출력하는 함수이다. – 예제 printf1.c 참조 printf 는 특수 문자 출력이 가능하다. 특수 문자의 미 \a 경고음 소리 발생 \b 백스페이스 (backspace)
C 프로그래밍 기초.
제12장 표준 입출력과 파일 입출력.
쉽게 풀어쓴 C언어 Express 제11장 포인터 C Express Slide 1 (of 27)
2장. 프로그램의 기본 구성. 2장. 프로그램의 기본 구성 2-1"Hello, World!" 들여다 보기 /* Hello.c */ #include int main(void) { printf("Hello, World! \n"); return 0;
제14장 동적 메모리.
쉽게 풀어쓴 C언어 Express 제16장 파일 입출력 C Express.
쉽게 풀어쓴 C언어 Express 제16장 파일 입출력 C Express.
쉽게 풀어쓴 C언어 Express 제16장 파일 입출력 C Express.
-Part3- 제3장 콘솔 입출력과 파일 입출력.
C 프로그래밍 소개 숙명여대 창병모 2011 가을.
Chapter 10– 표준 함수(1) Outline 10.1 스트림과 파일 10.2 입출력 표준 함수
제 9 장 구조체와 공용체.
쉽게 풀어쓴 C언어 Express 제18장 입출력과 라이브러리 함수 C Express.
데이터 파일 C 데이터 파일과 스트림(Stream) 텍스트 파일 처리
조 병 규 Software Quality Lab. 한국교통대학교
쉽게 풀어쓴 C언어 Express 제16장 파일 입출력 C Express Slide 1 (of 23)
기초C언어 제14주 전처리 및 비트 필드, 스트림과 파일 입출력(15,16장) 컴퓨터시뮬레이션학과 2016년 봄학기
HW#1 Source 파일 제출 3.20(수)까지 제출 학번_이름_01.c
Part 14 파일 입출력 ©우균, 창병모 ©우균, 창병모.
C언어를 이용한 화일처리.
제15장 파일 입출력 문자열을 출력하는 여러가지 방법 (15-2쪽) 문자열만 처리하는 입출력 함수
쉽게 풀어쓴 C언어 Express 제17장 동적메모리와 연결리스트 C Express Slide 1 (of 13)
Dynamic Memory and Linked List
11장. 포인터 01_ 포인터의 기본 02_ 포인터와 Const.
21장. 문자와 문자열 처리 함수.
9장 파일 입출력.
윤성우의 열혈 C 프로그래밍 윤성우 저 열혈강의 C 프로그래밍 개정판 Chapter 24. 파일 입출력.
SqlParameter 클래스 선문 비트 18기 발표자 : 박성한.
처음으로 배우는 C 프로그래밍 제5부 추가적인 화제들 제 11 장 파일 처리.
컴퓨터 프로그래밍 기초 #02 : printf(), scanf()
파일 기술자 복사 파일 기술자 복사 : dup(2) 파일 기술자 복사 : dup2(3)
12장 파일처리와 매크로 파일 입출력 함수 문자 입출력 함수 라인 입출력 함수 불록 입출력 함수 매크로.
Chapter 11 Strings.
Chapter 4. 보조자료 - 파일 입출력 파일의 기본 개념과 특징을 이해한다. 파일 처리 과정을 이해한다.
C언어 프로그래밍의 이해 Ch14. 파일 입출력.
11 표준 입출력과 파일 입출력 데이터를 읽고 쓰는 다양한 방법 익히기!.
6장. printf와 scanf 함수에 대한 고찰
프로그래밍 랩 – 7주 리스트.
TCP/IP Socket Programming…
14주차.
14장. 포인터와 함수에 대한 이해.
11장. 1차원 배열.
10장 C 표준 파일 입출력 子曰 學而時習(실습?)之 不亦悅乎.
Chapter 13 Input/Output and Files
9장 파일 입출력.
17강 파일처리함수(1) 강 의 내 용 파일 입출력의 개념 파일포인터를 이용한 입출력 파일 입출력 과정
18강 파일처리함수(2) 강 의 내 용 순차파일 만들기와 읽기 순차파일 입출력함수 랜덤파일 처리
Linux Programming Spring 2008
13. 포인터와 배열! 함께 이해하기 IT응용시스템공학과 김 형 진 교수.
3장 상수 변수 기본 자료형 키워드와 식별자 상수와 변수 기본 자료형 형변환 자료형의 재정의.
24장. 파일 입출력.
쉽게 풀어쓴 C언어 Express 제14장 포인터 활용 C Express Slide 1 (of 22)
Chapter 7 Text Files.
컴퓨터 프로그래밍 기초 - 10th : 포인터 및 구조체 -
Choi Seong Yun 컴퓨터 프로그래밍 기초 #03 : 변수와 자료형 Choi Seong Yun
파일 입출력.
4장. 데이터 표현 방식의 이해. 4장. 데이터 표현 방식의 이해 4-1 컴퓨터의 데이터 표현 진법에 대한 이해 n 진수 표현 방식 : n개의 문자를 이용해서 데이터를 표현 그림 4-1.
구조체(struct)와 공용체(union)
실습과제 1번 생성된 파일 basic.txt를 프로젝트 폴더에서 메모장으로 열고 내용을 확인
Chapter 12 파일 입출력.
C 13장. 입출력 라이브러리 #include <stdio.h> int main(void) { int num;
어서와 C언어는 처음이지 제21장.
윈도우에서의 유니코드.
개정판 누구나 즐기는 C언어 콘서트 제13장 동적 메모리 출처: pixabay.
2019 1학기 응용프로그래밍 - 파일 처리 01 파일 열기 02 파일 저장과 내용 읽기 03 이진파일 처리 04 임의접근 파일 처리 05 파일 관련 함수들.
13. 포인터와 배열! 함께 이해하기.
개정판 누구나 즐기는 C언어 콘서트 제12장 파일 입출력 출처: pixabay.
⊙ 입출력 처리란? data를 입력장치로부터 program 내부로 읽어 들이거나
Presentation transcript:

쉽게 풀어쓴 C언어 Express 제16장 스트림과 파일 입출력 C Express

입출력에 관련된 개념들과 함수들에 대하여 학습한다. 이번 장에서 학습할 내용 입출력에 관련된 개념들과 함수들에 대하여 학습한다. 입출력 형식 스트림의 개념 파일 입출력 입출력 관련 함수

출력 형식 지정자 출력 형식 지정자(format specification) 변환 지정자(conversion specification) 문자, 정수, 실수 등 출력 타입 명시 (변환 문자) 출력 필드의 크기 명시 %[플래그][필드폭][.정밀도]형식문자 정렬 방식, 부호 출력, 공백 문자 출력, 소수점, 8/16진수 접두사 출력 등 명시 소수점 이하 자릿수 명시

출력 형식 지정자 123.456000 1.230000e+001 1.23e+002 1.230000E+001

필드폭과 정밀도

필드폭과 정밀도

형식 플래그(format flag) - + # 플래그 기능 기본 값 space(' ') 왼쪽 정렬 오른쪽 정렬 항상 +/- 부호 출력 (0인 경우에도 + 부호 출력) 음수만 - 부호 출력 오른쪽 정렬 방식의 숫자 출력에서 왼쪽 빈 부분을 공백 문자 대신 0으로 채움 공백으로 채움 space(' ') 0이나 양수 출력에서 부호 대신 공백 출력 공백을 출력하지 않음 # 8진수 출력에서 앞에 0 출력 16진수 출력에서 앞에 0x/0X 출력 0/0x/0X를 출력하지 않음

입력 형식 필드폭을 지정하여 입력 8진수, 16진수 입력 #include <stdio.h> int main( ) { int a, b; printf("5자리 정수 입력: "); scanf("%3d %3d", &a, &b); // 최대 3문자씩 입력 printf("a = %d, b = %d\n", a, b);          return 0; } #include <stdio.h> int main() { int d, o, x; sscanf("10 10 10", "%d %o %x", &d, &o, &x); printf("d = %d, o = %d, x = %d\n", d, o, x);          return 0; } d = 10, o = 8, x = 16 5자리 정수 입력: 12345 a = 123, b = 45

문자와 문자열 입력 형식 지정자 설명 %c %s %[…] %[^…] char 형으로 문자 입력 공백 문자가 아닌 문자부터 공백 문자가 올 때까지 문자열 입력 %[…] 괄호 안에 속한 문자로 이루어진 문자열 입력 괄호 안에 0-9 같이 범위 표현 허용 예) %[_a-zA-Z] : 밑줄 문자, 영문자 예) %[-+0-9.eE] : 부호(-+), 숫자, 소수점(.), 지수 문자(eE) %[^…] 괄호 안에 속하지 않는 문자로 이루어진 문자열 입력 범위 표현 허용 scan set(문자 집합)

문자 입력과 공백 문자

예제: 문자열 입력 #include <stdio.h> int main(void) { char c, s[80], t[80]; printf("공백으로 분리된 문자열 입력: "); scanf("%s%c%s", s, &c, t); printf("첫번째 문자열=%s\n", s); printf("중간 공백 문자=%c\n", c); printf("두번째 문자열=%s\n", t); return 0; } 공백으로 분리된 문자열 입력: Hello World 첫번째 문자열=Hello 중간 공백 문자= 두번째 문자열=World

예제: 문자 집합 입력 #include <stdio.h> int main(void) { char s[80]; printf("문자열 입력: "); scanf("%[abc]", s); printf("입력된 문자열 = %s\n", s); return 0; } 문자열 입력: accbadae 입력된 문자열 = accba

예제: scanf 반환 값 #include <stdio.h> int main(void) { int x, y, z; if (scanf("%d %d %d", &x, &y, &z) == 3) printf("정수들의 합 = %d\n", x + y + z); else printf("입력 오류\n"); return 0; } 10 20 30 정수들의 합 = 60 10 20 a 입력 오류

scanf 사용시 주의점 입력 값을 저장할 변수의 주소 전달 int i; scanf("%d", &i); // OK scanf("%d", i); // ERROR 배열의 이름은 배열을 가리키는 포인터 char str[80]; scanf("%s", str); // OK scanf("%s", &str); // ERROR 충분한 공간 확보 char str[80]; scanf("%s", str); // 입력된 문자가 80개 이상이면 오류 형식 문자열 끝에 '\n'을 사용하지 말 것 int i; scanf("%d\n", &i); scanf("%d\n", &i); printf("%d\n", i); 12 ↵ ↵ 3 12

스트림의 개념 스트림(stream): 입력과 출력을 바이트의 흐름으로 생각하는 것

스트림과 버퍼 스트림에는 일반적으로 버퍼(buffer)가 사용됨

FILE과 표준 스트림 스트림은 C에서 FILE 구조체로 표현 typedef struct { … } FILE; // <stdio.h> 표준 스트림(standard stream)은 자동으로 생성됨 FILE *stdin, *stdout, *stderr; // <stdio.h> 변수 스트림 기본 연결 장치 stdin 표준 입력 스트림 키보드 stdout 표준 출력 스트림 모니터 화면 stderr 표준 오류 스트림

입출력 함수의 분류 사용하는 스트림에 따른 분류 입출력 형식 사용 여부에 따른 분류 표준 입출력 스트림을 사용하는 함수 스트림을 구체적으로 명시해야 하는 함수 입출력 형식 사용 여부에 따른 분류 입출력 형식을 사용하지 않는 함수: unformatted I/O 입출력 형식을 사용하는 함수: formatted I/O 입출력 형식 표준 스트림 일반 스트림 기능 형식이 없는 입출력 (문자/문자열) getchar( ) fgetc( ), getc( ) 문자 입력 putchar( ) fputc( ), putc( ) 문자 출력 gets( ) fgets( ) 문자열 입력 puts( ) fputs( ) 문자열 출력 형식이 있는 입출력 (정수, 실수, …) scanf( ) fscanf( ) 형식화된 입력 printf( ) fprintf ( ) 형식화된 출력

파일 파일에 저장된 데이터는 프로그램 실행이 끝나도 보존됨 C에서 파일은 일련의 연속된 바이트 모든 파일 데이터는 결국 바이트들로 파일에 저장 파일 데이터에 대한 해석은 프로그래머에게 달려 있음 예: 파일의 4개 바이트  int, float, 픽셀, … 하나의 정수? 하나의 실수? 4개의 문자? 0x36 0x34 0x31 0x0

텍스트 파일(text file) 사람이 읽을 수 있는 텍스트가 들어 있는 파일 예: C 프로그램 소스 파일, 메모장 파일 아스키 코드, 한글 코드, 유니코드 등을 사용하여 저장 라인들로 구분됨: 운영체제에 따라 라인 끝 표지가 다름 ‘W’ ‘O’ ‘R’ ‘L’ ‘D’ ‘\r’ ‘\n’ 윈도우, MS_DOS 유닉스, 리눅스 매킨토시 C언어

이진 파일(binary file) 사람이 직접 읽을 수는 없고 컴퓨터가 처리하기 위한 파일 예: C 프로그램 실행 파일, 사운드 파일, 이미지 파일 이진 데이터를 직접 저장 문자열로 변환하지 않고 입출력 라인들로 구분되지 않음

파일 처리 개요 파일 처리 순서 FILE 구조체를 이용 FILE *: 파일 포인터(file pointer) 파일 열기 (open) 파일 읽기/쓰기 (read/write) 파일 닫기 (close)

파일 열기와 닫기 FILE *fopen(const char *name, const char *mode); 파일 열기 함수 mode: 파일 모드(file mode) 열기 실패의 경우 NULL 포인터 반환 int fclose(FILE *stream); 파일 닫기 함수 반환 값: 성공  0, 실패  EOF FILE *fp; fp = fopen("test.txt", "r"); if (fp == NULL) // if (!fp) printf("test.txt: open fail\n"), exit(1); … fclose(fp); FILE *fp; if (!(fp = fopen("test.txt", "r"))) printf("test.txt: open fail\n"), exit(1); … fclose(fp);

파일 모드 모드 설명 "r" 읽기(read), 파일이 없으면 열기 실패 "w" 쓰기(write), 파일이 없으면 새로 생성, 이미 존재하면 기존 내용 삭제 "a" 추가(append), 파일이 없으면 새로 생성, 이미 존재하면 기존 내용 보존, 항상 파일 끝에 쓰기 "r+" 수정(update: read/write), 파일이 없으면 열기 실패 "w+" 수정, 파일이 없으면 새로 생성, 이미 존재하면 기존 내용 삭제 "a+" 수정, 파일이 없으면 새로 생성, 이미 존재하면 기존 내용 보존, 이진 파일이면 끝에 b 추가 "rb", "wb", "ab", "r+b", "w+b", "a+b" 텍스트 파일이면 끝에 t 추가 또는 생략 "r", "w", "a", "r+", "w+", "a+", "rt", "wt", "at", "r+t", "w+t", "a+t" 수정 모드에서 읽기쓰기, 쓰기읽기 전환 시, 반드시 fflush(), fseek(), fsetpos(), rewind() 중 하나를 먼저 호출해야 함

파일 삭제 int remove(const char *path); 파일 삭제 함수 반환 값: 성공  0, 실패  0이 아닌 값 파일 포인터를 사용하지 않는 함수 if (remove("test.txt")) printf("test.txt: 삭제 실패\n");

크게 텍스트 입출력과 이진 데이터 입출력으로 구분할 수 있습니다. 파일 입출력 함수 설명 입력 함수 출력 함수 문자 입출력 fgetc( ), getc( ) fputc( ), putc( ) 문자열 입출력 fgets() fputs( ) 형식화된 입출력 fscanf( ) fprintf( ) 이진 데이터 입출력 fread( ) fwrite( ) 크게 텍스트 입출력과 이진 데이터 입출력으로 구분할 수 있습니다.

문자 입출력 int fgetc(FILE *fp); int getc(FILE *fp); 문자 입력 fgetc  함수; getc  일반적으로 매크로 반환 값: 성공  입력된 문자, 실패(파일 끝, 에러)  EOF #define getchar( ) getc(stdin) int fputc(int c, FILE *fp); int putc(int c, FILE *fp); 문자 출력 fputc  함수; putc  일반적으로 매크로 반환 값: 성공  출력된 문자(c), 실패(에러)  EOF #define putchar(c) putc((c), stdout)

문자 입출력 #include <stdio.h> int main(void) { FILE *fp;   #include <stdio.h> int main(void) { FILE *fp; fp = fopen("sample.txt", "w"); if (fp == NULL) return printf("파일 열기 실패\n"), 1; else printf("파일 열기 성공\n"); putc('a', fp); putc('b', fp); putc('c', fp); // fputc('a', fp); fputc('b', fp); fputc('c', fp); fclose(fp); return 0; } sample.txt abc 파일 열기 성공

문자 입출력 #include <stdio.h> int main(void) { FILE *fp; int c;   #include <stdio.h> int main(void) { FILE *fp; int c; if (!(fp = fopen("sample.txt", "r"))) return printf("파일 열기 실패\n"), 1; while ((c = getc(fp)) != EOF) // c = fgetc(fp) putchar(c); fclose(fp); return 0; } sample.txt abc abc

문자열 입출력 char *fgets(char *s, int n, FILE *fp); s에 한 라인의 문자열 입력 최대 n-1 문자만 입력  안전함, 공백 문자들도 입력, '\n'도 저장 반환 값: 성공  s, 실패(파일 끝, 에러)  NULL char *gets(char *s): stdin에서 입력 무조건 한 라인 입력  위험함 '\n'을 읽어들이지만 저장하지는 않음 int fputs(const char *s, FILE *fp); 문자열 s 출력 반환 값: 성공  음수가 아닌 값, 실패(에러)  EOF int puts(const char *s): stdout에 출력 s를 출력한 후 '\n' 출력

문자열 입출력 char s[100]; fputs(fgets(s, 6, stdin), stdout); s ab cd\0 ab cde\n ab cd char s[100]; fputs(fgets(s, 10, stdin), stdout); char s[100]; puts(gets(s)); s s ab cde\n\0 ab cde\0 ab cde\n ab cde\n

문자열 입출력 #include <stdio.h> #include <stdlib.h> int main(void) { FILE *fp1, *fp2; char file1[100], file2[100]; char buffer[100]; printf("원본 파일: "); scanf("%s", file1); printf("복사 파일: "); scanf("%s", file2); if (!(fp1 = fopen(file1, "r"))) { fprintf(stderr,"%s: 열기 실패\n", file1); exit(1); } if (!(fp2 = fopen(file2, "w"))) { fprintf(stderr,"%s: 열기 실패\n", file2); while (fgets(buffer, 100, fp1) != NULL) fputs(buffer, fp2); fclose(fp1); fclose(fp2); return 0; } 원본 파일: a.txt 복사 파일: b.txt a.txt C 프로그래밍 C Programming b.txt C 프로그래밍 C Programming

문자열 입출력 proverb.txt #include <stdio.h> #include <stdlib.h> #include <string.h> int main(void) { char *fname = "proverb.txt"; FILE *fp; int line_num = 0; char line[256], word[256]; printf("탐색할 단어: "); scanf("%s", word); if (!(fp = fopen(fname, "r"))) fprintf(stderr,"%s: 열기 실패\n", fname), exit(1); while (fgets(line, 256, fp)) { line_num++; if (strstr(line, word)) printf("%s:%d -- %s 발견\n", fname, line_num, word); } fclose(fp); return 0; A house divided against itself cannot stand. A good man is hard to find. A house is not a home. A friend in need is a friend indeed. 탐색할 단어: house proverb.txt:1 -- house 발견 proverb.txt:3 -- house 발견

형식화된 입출력 printf("...", …): fprintf(stdout, "...", …) int fprintf(FILE *fp, const char *format, ...); int fscanf(FILE *fp, const char *format, ...); printf("...", …): fprintf(stdout, "...", …) scanf("...", …): fscanf(stdin, "...", …) FILE *fp; int i = 123; float f = 1.23F; if ((fp = fopen("sample.txt", "w"))) { fprintf(fp, "%d %.2f\n", i, f); fclose(fp); } FILE *fp; int i; float f; if ((fp = fopen("sample.txt", "r"))) { fscanf(fp, "%d %f", &i, &f); printf("%d %.2f", i, f); fclose(fp); } sample.txt 123 1.23 123 1.23

예제 #include <stdio.h> typedef struct { int number; char name[20]; float score; } Student; int main(void) { FILE *fp; char fname[100]; int count = 0; float total = 0.0F; Student s; printf("성적 파일: "); scanf("%s", fname); if (!(fp = fopen(fname, "w"))) return fprintf(stderr,"%s: 열기 실패\n", fname), 1; while (1) { printf("학번, 이름, 성적 입력: "); if (scanf("%d %s %f", &s.number, s.name, &s.score) != 3) break; fprintf(fp, "%d %s %g\n", s.number, s.name, s.score); } fclose(fp); if (!(fp = fopen(fname, "r"))) while (fscanf(fp, "%d %s %f", &s.number, s.name, &s.score) == 3) total += s.score, count++; printf("평균 = %g\n", total / count); return 0; 성적 파일: score.txt 학번, 이름, 성적 입력: 1 KIM 90.2 학번, 이름, 성적 입력: 2 PARK 30.5 학번, 이름, 성적 입력: 3 MIN 56.8 학번, 이름, 성적 입력: ^Z 평균 = 59.1667 1 KIM 90.2 2 PARK 30.5 3 MIN 56.8 score.txt

버퍼링(buffering) fopen()을 사용하여 파일을 열면 자동으로 버퍼(buffer) 할당 버퍼는 입출력 데이터의 임시 저장 장소로 이용되는 메모리 블록 디스크 장치는 블록 단위로 입출력할 경우 효율적으로 동작 블록의 크기는 일반적으로 512바이트의 배수 예: 512, 1024, 4096, 8192 flush: 버퍼의 내용을 비우는 동작 fclose(): flush  버퍼 반납 buffered I/O: 버퍼를 이용하는 입출력 File Buffer Program 물리적 입출력 (Physical I/O) 논리적 입출력 (Logical I/O)

fflush, feof, ferror int fflush(FILE *fp); 출력 스트림의 경우, 버퍼의 내용을 실제 파일에 저장하고 버퍼를 비움 입력 스트림에 대한 동작은 OS에 따라 다름 반환 값: 성공  0, 실패  EOF int feof(FILE *fp); 현재 파일 끝 상태이면 참(0이 아닌 값) 반환 int ferror(FILE *fp); 현재 파일이 에러 상태이면 참(0이 아닌 값) 반환

이진 데이터 파일 메모리의 내부 데이터 표현 형식 그대로 저장

이진 데이터 출력 size_t fwrite(const void *buffer, size_t size, size_t count, FILE *fp); buffer에서 크기가 size인 항목을 count 개수만큼 출력 반환 값: 출력된 항목 개수 반환 값이 count가 아니면 에러 FILE *fp; int a[ ] = { 10, 20, 30, 40, 50 }; size_t size = sizeof a[0]; size_t n = sizeof a / sizeof a[0]; if ((fp = fopen("data.bin", "wb"))) { if (fwrite(a, size, n, fp) != n) fprintf(stderr, "출력 실패\n"); fclose(fp); } int a[5] = { 10, 20, 30, 40, 50 }; if (fwrite(a, sizeof a, 1, fp) != 1) // error if (fwrite(a, sizeof a[0], 5, fp) != 5) // error

이진 데이터 입력 size_t fread(void *buffer, size_t size, size_t count, FILE *fp); buffer에 크기가 size인 항목을 최대 count 개수만큼 입력 반환 값: 입력된 항목 개수 반환 값이 count보다 작으면 파일 끝이나 에러 #define SIZE 100 FILE *fp; int a[SIZE]; size_t n; if ((fp = fopen("data.bin", "rb"))) { n = fread(a, sizeof a[0], SIZE, fp); if (n < SIZE) fprintf(stderr, "파일 끝 또는 입력 실패\n"); fclose(fp); }

예제: 파일 복사 #include <stdio.h> #include <stdlib.h> #define USAGE "Usage: fcopy from to\n" #define BUF_SIZE 1024 int main(int argc, char *argv[ ]) { FILE *fpi, *fpo; char buf[BUF_SIZE]; size_t n; if (argc != 3) fprintf(stderr, "%s", USAGE), exit(1); if (!(fpi = fopen(argv[1], "rb"))) fprintf(stderr, "%s: fail to open\n", argv[1]), exit(1); if (!(fpo = fopen(argv[2], "wb"))) fprintf(stderr, "%s: fail to open\n", argv[2]), exit(1);     while ((n = fread(buf, 1, BUF_SIZE, fpi)) > 0)         if (fwrite(buf, 1, n, fpo) != n) break;          if (ferror(fpi))         fprintf(stderr, "%s: fail to read\n", argv[1]), exit(1);     if (ferror(fpo))         fprintf(stderr, "%s: fail to write\n", argv[2]), exit(1);     fprintf(stderr, "copied: %s => %s\n", argv[1], argv[2]);     fclose(fpi); fclose(fpo);     return 0; } C> fcopy fcopy.exe fcopy2.exe copied: fcopy.exe => fcopy2.exe

예제: 파일 추가 // 첫 번째 파일을 두 번째 파일 끝에 추가 #include <stdio.h> #include <stdlib.h> #define BUF_SIZE 1024 int main(void) { FILE *fp1, *fp2; char file1[100], file2[100]; char buffer[BUF_SIZE]; int n; printf("입력 파일: "); scanf("%s", file1); printf("추가할 파일: "); scanf("%s", file2); if (!(fp1 = fopen(file1, "rb"))) fprintf(stderr,"입력 파일 열기 실패\n"), exit(1); if (!(fp2 = fopen(file2, "ab"))) fprintf(stderr,"추가할 파일 열기 실패\n"), exit(1); while ((n = fread(buffer, 1, BUF_SIZE, fp1)) > 0) fwrite(buffer, 1, n, fp2); fclose(fp1); fclose(fp2); return 0; } 입력 파일: a.dat 추가할 파일: b.dat

예제: 이진 데이터 입출력 #include <stdio.h> #include <stdlib.h> #define SIZE 3 typedef struct { int number; char name[20]; double gpa; } Student; int main(void) { Student table[SIZE] = { { 1, "Kim", 3.99 }, { 2, "Min", 2.68 }, { 3, "Lee", 4.01 } }; Student s; FILE *fp; int i; if (!(fp = fopen("student.dat", "wb"))) fprintf(stderr,"출력 파일 열기 실패\n"), exit(1); if (fwrite(table, sizeof(Student), SIZE, fp) != SIZE) fprintf(stderr,"파일 출력 실패\n"), exit(1); fclose(fp); if (!(fp = fopen("student.dat", "rb"))) fprintf(stderr,"입력 파일 열기 실패\n"), exit(1); for (i = 0; i < SIZE; i++) { if (fread(&s, sizeof s, 1, fp) != 1) fprintf(stderr,"파일 입력 실패\n"), exit(1); printf("%d, %s, %g\n", s.number, s.name, s.gpa); } fclose(fp); return 0; 1, Kim, 3.99 2, Min, 2.68 3, Lee, 4.01

예제: Hexa Dump // 16진수로 파일 내용 출력 #include <stdio.h> #include <stdlib.h> #include <ctype.h> int main(void) { FILE *fp; char fname[100]; unsigned char buffer[16]; int address = 0; int i, bytes; printf("파일 이름: "); scanf("%s", fname); if (!(fp = fopen(fname, "rb"))) fprintf(stderr,"%s: 열기 실패\n", fname), exit(1); while ((bytes = fread(buffer, 1, 16, fp)) > 0) { printf("%08X: ", address); address += bytes; for (i = 0; i < bytes; i++) printf("%02X ", buffer[i]); for ( ; i < 16; i++) printf(" "); for (i = 0; i < bytes; i++) putchar(isprint(buffer[i]) ? buffer[i] : '.'); putchar('\n'); } fclose(fp); return 0; in.html <html> <body> <pre> <h1>Build Log</h1> 파일 이름: in.html 00000000: 3C 68 74 6D 6C 3E 0D 0A 3C 62 6F 64 79 3E 0D 0A <html>..<body>.. 00000010: 3C 70 72 65 3E 0D 0A 3C 68 31 3E 42 75 69 6C 64 <pre>..<h1>Build 00000020: 20 4C 6F 67 3C 2F 68 31 3E 0D 0A Log</h1>..

임의 접근 순차 접근(sequential access): 파일의 처음부터 차례대로 입출력 임의 접근(random access): 파일의 임의 위치에서 직접 입출력  직접 접근(direct access) 파일 위치(file position) 표시자 바이트 단위로 현재 입출력 위치 정보 유지 첫 번째 바이트: 0번째 바이트 파일 위치를 이동시키면 임의 접근 가능 순차 접근 임의 접근 파일 위치 표시자 1 2 3 4 5 6 7

임의 접근 관련 함수 int fseek(FILE *fp, long offset, int origin); origin 기준으로 offset만큼 떨어진 바이트로 파일 위치 변경 offset이 음수: 파일 시작 쪽으로 이동 offset이 양수: 파일 끝 쪽으로 이동 반환 값: 성공  0, 실패  0이 아닌 값 origin 값 기준 위치 SEEK_SET 파일 시작 SEEK_CUR 1 현재 위치 SEEK_END 2 파일 끝 fseek(fp, 0L, SEEK_SET); // 파일 시작으로 이동 (SEEK_SET이면 offset은 절대 위치) fseek(fp, 100L, SEEK_SET); // 100번째 바이트로 이동 fseek(fp, 0L, SEEK_END); // 파일 끝으로 이동 fseek(fp, -20L, SEEK_END); // 파일 끝에서 시작 쪽으로 20바이트 이동 fseek(fp, 50L, SEEK_CUR); // 현재 위치에서 끝 쪽으로 50바이트 이동 fseek(fp, sizeof(struct element), SEEK_CUR); // 구조체 크기만큼 파일 위치 증가 long ftell(FILE *fp); void rewind(FILE *fp); 현재 파일 위치 반환 에러  -1 반환 파일 위치를 0으로 변경 파일 시작 위치로 이동

예제 #include <stdio.h> #include <stdlib.h> #define SIZE 1000 int main(void) { FILE *fp; int table[SIZE], data, n; long pos; for (n = 0; n < SIZE; n++) table[n] = n * n; fp = fopen("sample.dat", "wb"); fwrite(table, sizeof table, 1, fp); fclose(fp); fp = fopen("sample.dat", "rb"); while (1) { printf("데이터 위치(0 ~ %d): ", SIZE - 1); scanf("%d", &n); if (n < 0 || n >= SIZE) break; pos = (long)(n * sizeof(int)); if (fseek(fp, pos, SEEK_SET)) fprintf(stderr, "fseek 실패\n"), exit(1); fread(&data, sizeof(int), 1, fp); printf("%d: %d\n", n, data); } fclose(fp); return 0; 데이터 위치(0 ~ 999): 3 3: 9 데이터 위치(0 ~ 999): 9 9: 81 데이터 위치(0 ~ 999): -1