표준입출력스트림 기본적인스트림들은프로그래머가생성하지않아도자동으로생성된다. 이름스트림연결장치 stdin 표준입력스트림키보드 stdout 표준출력스트림모니터의화면 stderr 표준오류스트림모니터의화면 입출력함수의분류 사용하는스트림에따른분류 표준입출력스트림을사용하여입출력을하

Similar documents
Microsoft PowerPoint - Lesson13.pptx

11장 포인터

<4D F736F F F696E74202D20C1A63136C0E520C6C4C0CFC0D4C3E2B7C2>

chap7.key

Microsoft PowerPoint - chap13-입출력라이브러리.pptx

歯9장.PDF

<4D F736F F F696E74202D2034C5D8BDBAC6AEC6C4C0CFC0D4C3E2B7C2312E505054>

Microsoft PowerPoint - 제11강 파일 처리

PowerPoint 프레젠테이션

PowerPoint 프레젠테이션

PowerPoint 프레젠테이션

금오공대 컴퓨터공학전공 강의자료

쉽게 풀어쓴 C 프로그래밍

PowerPoint Template

Microsoft PowerPoint - chap11.ppt [호환 모드]

Microsoft PowerPoint - chap4 [호환 모드]

Microsoft PowerPoint - Chap14_FileAccess.pptx

슬라이드 1


슬라이드 1

11장 포인터

제1장 Unix란 무엇인가?

Microsoft PowerPoint - 09_(C_Programming)_(Korean)_File_Processing

C Programming

<4D F736F F F696E74202D20B8AEB4AABDBA20BFC0B7F920C3B3B8AEC7CFB1E22E BC8A3C8AF20B8F0B5E55D>

<322EBCF8C8AF28BFACBDC0B9AEC1A6292E687770>

제7장 C 표준 파일 입출력

BMP 파일 처리

Microsoft PowerPoint - chap11-1.ppt [호환 모드]

13 주차문자열의표현과입출력

<4D F736F F F696E74202D D20B9AEC0DABFAD2C20BDBAC6AEB8B2B0FA20C6C4C0CF20C0D4C3E2B7C2>

제7장 C 표준 파일 입출력

Microsoft PowerPoint - 10_C_Language_Text_Files

< E20C6DFBFFEBEEE20C0DBBCBAC0BB20C0A7C7D12043BEF0BEEE20492E707074>

윤성우의 열혈 TCP/IP 소켓 프로그래밊

제 14 장포인터활용 유준범 (JUNBEOM YOO) Ver 본강의자료는생능출판사의 PPT 강의자료 를기반으로제작되었습니다.

본 강의에 들어가기 전

Microsoft PowerPoint APUE(Intro).ppt

중간고사

윤성우의 열혈 TCP/IP 소켓 프로그래밊

Microsoft PowerPoint - chap02-C프로그램시작하기.pptx

untitled

Microsoft PowerPoint - chap11-포인터의활용.pptx

설계란 무엇인가?

슬라이드 1

제1장 Unix란 무엇인가?

PowerPoint Presentation

본 강의에 들어가기 전

이번장에서학습할내용 동적메모리란? malloc() 와 calloc() 연결리스트 파일을이용하면보다많은데이터를유용하고지속적으로사용및관리할수있습니다. 2

<4D F736F F F696E74202D20C1A63137C0E520B5BFC0FBB8DEB8F0B8AEBFCD20BFACB0E1B8AEBDBAC6AE>

untitled

0. 표지에이름과학번을적으시오. (6) 1. 변수 x, y 가 integer type 이라가정하고다음빈칸에 x 와 y 의계산결과값을적으시오. (5) x = (3 + 7) * 6; x = 60 x = (12 + 6) / 2 * 3; x = 27 x = 3 * (8 / 4

11장 포인터


02장.배열과 클래스

OCW_C언어 기초

C 언어 프로그래밊 과제 풀이

ABC 11장

C 프로그램의 기본

Microsoft PowerPoint - ch07 - 포인터 pm0415

프로그래밍개론및실습 2015 년 2 학기프로그래밍개론및실습과목으로본내용은강의교재인생능출판사, 두근두근 C 언어수업, 천인국지음을발췌수정하였음

금오공대 컴퓨터공학전공 강의자료

제12장 파일 입출력

PowerPoint 프레젠테이션

Microsoft PowerPoint - chap06-1Array.ppt

untitled

Microsoft PowerPoint - C프로그래밍-chap15.ppt [호환 모드]

Microsoft PowerPoint - chap10-함수의활용.pptx

슬라이드 1

비트와바이트 비트와바이트 비트 (Bit) : 2진수값하나 (0 또는 1) 를저장할수있는최소메모리공간 1비트 2비트 3비트... n비트 2^1 = 2개 2^2 = 4개 2^3 = 8개... 2^n 개 1 바이트는 8 비트 2 2

2007_2_project4

Microsoft PowerPoint - C_Programming_Basics.ppt [호환 모드]

PowerPoint 프레젠테이션

Microsoft PowerPoint - Ch12.파일.pptx

Microsoft PowerPoint - chap03-변수와데이터형.pptx

Microsoft PowerPoint - [2009] 02.pptx

Microsoft PowerPoint - 3ÀÏ°_º¯¼ö¿Í »ó¼ö.ppt

11장 포인터

<4D F736F F F696E74202D D20B9AEC0DABFAD2C20BDBAC6AEB8B2B0FA20C6C4C0CF20C0D4C3E2B7C2>

03 상수, 변수, 자료형

11장 포인터

<4D F736F F F696E74202D20C1A633C0E52043C7C1B7CEB1D7B7A5B1B8BCBABFE4BCD2>

11장 포인터

PowerPoint 프레젠테이션

<443A5C4C C4B48555C B3E25C32C7D0B1E25CBCB3B0E8C7C1B7CEC1A7C6AE425CBED0C3E0C7C1B7CEB1D7B7A55C D616E2E637070>

Microsoft PowerPoint - [CPI16] Lecture 10 - 문자열.pptx

: 1 int arr[9]; int n, i; printf(" : "); scanf("%d", &n); : : for(i=1; i<10; i++) arr[i-1] = n * i; for(i=0; i<9; i++) if(i%2 == 1) print


; struct point p[10] = {{1, 2, {5, -3, {-3, 5, {-6, -2, {2, 2, {-3, -3, {-9, 2, {7, 8, {-6, 4, {8, -5; for (i = 0; i < 10; i++){ if (p[i].x > 0 && p[i

1.2 자료형 (data type) 프로그램에서다루는값의형태로변수나함수를정의할때주로사용하며, 컴퓨터는선언된 자료형만큼의메모리를확보하여프로그래머에게제공한다 정수 (integer) 1) int(4 bytes) 연산범위 : (-2 31 ) ~ (2 31 /2)-

Microsoft PowerPoint - chap04-연산자.pptx

Microsoft PowerPoint - chap06-2pointer.ppt

Microsoft PowerPoint - chap4_2013 [호환 모드]

Microsoft PowerPoint - chap-12.pptx

Computer Programming (2008 Fall)

이번장에서학습할내용 문자표현방법 문자열표현방법 문자열이란무엇인가? 문자열의입출력 문자처리라이브러리함수 표준입출력라이브러리함수 인간은문자를사용하여정보를표현하므로문자열은프로그램에서중요한위치를차지하고있다. 이번장에서는 C 에서의문자열처리방법에대하여자세히살펴볼것입니다. 2

JAVA 프로그래밍실습 실습 1) 실습목표 - 메소드개념이해하기 - 매개변수이해하기 - 새메소드만들기 - Math 클래스의기존메소드이용하기 ( ) 문제 - 직사각형모양의땅이있다. 이땅의둘레, 면적과대각

PowerPoint 프레젠테이션

Lab 3. 실습문제 (Single linked list)_해답.hwp

제1장 Unix란 무엇인가?

Transcription:

쉽게풀어쓴 C 언어 Express 이번장에서학습할내용 제 16 장파일입출력 스트립의개념 표준입출력 파일입출력 입출력관련함수 입출력에관련된개념들과함수들에대하여학습한다. 스트림의개념 스트림 (stream): 입력과출력을바이트 (byte) 들의흐름으로생각하는것 스트림과버퍼 스트림에는기본적으로버퍼가포함되어있다. 1

표준입출력스트림 기본적인스트림들은프로그래머가생성하지않아도자동으로생성된다. 이름스트림연결장치 stdin 표준입력스트림키보드 stdout 표준출력스트림모니터의화면 stderr 표준오류스트림모니터의화면 입출력함수의분류 사용하는스트림에따른분류 표준입출력스트림을사용하여입출력을하는함수 스트림을구체적으로명시해주어야하는입출력함수 스트림형식표준스트림일반스트림설명 형식이없는입출력 ( 문자형태 ) 형식이있는입출력 ( 정수, 실수,..) getchar() fgetc(file *f,...) 문자입력함수 putchar() fputc(file *f,...) 문자출력함수 gets() fgets(file *f,...) 문자열입력함수 puts() fputs(file *f,...) 문자열출력함수 printf() fprintf(file *f,...) 형식화된출력함수 scanf() fscanf(file *f,...) 형식화된입력함수 입출력함수의분류 데이터의형식에따른분류 getchar() 나 putchar() 처럼문자형태의데이터를받아들이는입출력 printf() 나 scanf() 처럼구체적인형식을지정할수있는입출력 스트림과파일 스트림은구체적으로 FILE 구조체를통하여구현 FILE 은 stdio.h 에정의되어있다. 스트림형식표준스트림일반스트림설명 형식이없는입출력 ( 문자형태 ) 형식이있는입출력 ( 정수, 실수,..) getchar() fgetc(file *f,...) 문자입력함수 putchar() fputc(file *f,...) 문자출력함수 gets() fgets(file *f,...) 문자열입력함수 puts() fputs(file *f,...) 문자열출력함수 printf() fprintf(file *f,...) 형식화된출력함수 scanf() fscanf(file *f,...) 형식화된입력함수 2

중간점검 printf() 를이용한출력 1. C 에서의모든입력과출력을 형식으로처리된다. 2. 스트림은모든입력과출력을 들의흐름으로간주한다. 3. 스트림의최대장점은 이다. 4. 입력을위한표준적인스트림은 이고기본적으로 장치와연결된다. 5. 출력을위한표준적인스트림은 이고기본적으로 장치와연결된다. 형식제어문자열의구조 출력의정렬과부호출력, 공백문자출력, 소수점, 8 진수와 16 진수접두사출력 % [ 플래그 ] [ 필드폭 ] [. 정밀도 ] 형식 데이터가출력되는필드의크기 출력형식 정밀도는소수점이하자릿수의개수가된다. 형식지정자 실수의형식 3

필드폭과정밀도 필드폭과정밀도 플래그 플래그 기호의미기본값 - 출력필드에서출력값을왼쪽정렬한다. 오른쪽정렬된다. 음수일때만 - 부호를 + 결과값을출력할때항상 + 와 -의부호를붙인다. 붙인다. 출력값앞에공백문자대신에 0 으로채운다. - 와 0 blank( ) # 0이동시에있으면 0은무시된다. 만약정수출력채우지않는다. 의경우, 정밀도가지정되면역시 0은무시된다 ( 예를들어서 %08.5). 출력값앞에양수나영인경우에는부호대신공백공백을출력하지않는을출력한다. 음수일때는 -가붙여진다. + 플래그다. 가있으면무시된다. 8진수출력시에는출력값앞에 0을붙이고 16진붙이지않는다. 수출력시에는 0x를붙인다. 4

중간점검 1. printf() 에서변수나수식의값을출력하는형식을지정하는문자열은 이다. 2. printf() 에서정렬 (alignment) 을구체적으로지시하지않으면기본적으로 정렬된다. 3. 실수를지수표기법으로출력하는데사용되는형식지정자는 이다. 4. 정수를필드폭 6 으로출력하려면 % d 로하여야한다. 5. 실수를필드폭 10 이고소수점이하자리수를 6 자리로출력하려면 % f 로하여야한다. 6. 출력값을왼쪽정렬시키는플래그는 이다. 7. 실수출력의경우, 정밀도를지정하지않았을경우, 소수점이하자리수는기본적으로 개가된다. scanf() 를이용한입력 문자열형태의입력을사용자가원하는형식으로변환한다. 필드폭지정하여읽기 필드로지정하여서읽기 int a, b; printf("5 개의숫자로이루어진정수를입력하시오 : "); scanf("%3d%3d", &a, &b); printf(" 입력된정수는 %d, %d\n", a, b); 3 글자씩나우어서읽는다. 5 개의숫자로이루어진정수를입력하시오 : 123456 입력된정수는 123, 456 5

int d, o, x; 10 10 10 d=10 o=8 x=16 필드로지정하여서읽기 scanf("%d %o %x", &d, &o, &x); printf("d=%d o=%d x=%d\n", d, o, x); 분류문자형 형식지정자 문자와문자열입력 %c char 형으로입력받음 %s %[abc] %[^abc] %[0-9] 설명 공백문자가아닌문자부터공백문자가나올때까지를문자열로변환하여입력받음. 대괄호안에있는문자 a,b,c 로만이루어진문자열을읽어들인다. 대괄호안에있는문자 a,b,c 만을제외하고다른문자들로이루어진문자열을읽어들인다. 0 에서 9 까지의범위에있는문자들로이루어진문자열을읽어들인다. 문자와문자열읽기 scanf6.c char c; char s[80], t[80]; printf(" 스페이스로분리된문자열을입력하시오 :"); scanf("%s%c%s", s, &c, t); printf(" 입력된첫번째문자열 =%s\n", s); printf(" 입력된문자 =%c\n", c); printf(" 입력된두번째문자열 =%s\n", t); 스페이스로분리된문자열을입력하시오 :Hello World 입력된첫번째문자열 =Hello 입력된문자 = 입력된두번째문자열 =World 6

문자집합으로읽기 반환값이용 char s[80]; printf(" 문자열을입력하시오 :"); scanf("%[abc]", s); printf(" 입력된문자열 =%s\n", s); int x, y, z; if (scanf("%d%d%d", &x, &y, &z) == 3) printf(" 정수들의합은 %d\n", x+y+z); else printf(" 입력값이올바르지않습니다.\n"); 문자열을입력하시오 :abcdef 입력된문자열 =abc 10 20 30 정수들의합은 60 a b c 입력이올바르지않음 scanf() 사용시주의점 입력값을저장할변수의주소를전달 int i; scanf("%d", i); // 오류!! 배열의이름은배열을가리키는포인터 int str[80]; scanf("%s", str); // 올바름 scanf("%s", &str); // 오류!! scanf() 사용시주의점 충분한공간을확보 int str[80]; scanf("%s", str); // 입력된문자의개수가 79 를초과하면치명적인오류발생 scanf() 의형식제어문자열의끝에줄바꿈문자 '\n' 을사용하는것은해당문자가반드시입력되어야한다는의미 scanf("%d\n", &i);// 잘못됨!! 7

중간점검 파일이필요한이유 1. scanf() 에서 double 값을입력받을때사용하는형식지정자는 이다. 2. 여러개의입력을받는경우, scanf() 는 을이용하여각각의입력을분리한다 파일의개념 C 에서의파일은일련의연속된바이트 모든파일데이터들은결국은바이트로바뀌어서파일에저장 이들바이트들을어떻게해석하느냐는전적으로프로그래머의책임 파일 파일에 4 개의바이트가들어있을때이것을 int 형의정수데이터로도해석할수있고아니면 float 형실수데이터로도해석할수있다 하나의정수? 하나의실수? 4 개의문자? 파일 0x36 0x34 0x31 0x0 8

텍스트파일 (text file) 텍스트파일은사람이읽을수있는텍스트가들어있는파일 ( 예 ) C 프로그램소스파일이나메모장파일 텍스트파일은아스키코드를이용하여저장 텍스트파일은연속적인라인들로구성 W O R L D \r \n 이진파일 (binary file) 이진파일은사람이읽을수는없으나컴퓨터는읽을수있는파일 이진데이터가직접저장되어있는파일 이진파일은텍스트파일과는달리라인들로분리되지않는다. 모든데이터들은문자열로변환되지않고입출력 이진파일은특정프로그램에의해서만판독이가능 ( 예 ) C 프로그램실행파일, 사운드파일, 이미지파일 윈도우, MS_DOS W O R L D \n C 언어 W O R L D \n 유닉스 #include #include <stdlib.h> <stdio.h> #include <stdlib.h>... p=(int... *)malloc(100);... p=(int *)malloc(100);... W O R L D \r 매킨토시 텍스트파일 : 문자로구성된파일 이진파일 : 데이터로구성된파일 파일처리의개요 파일을다룰때는반드시다음과같은순서를지켜야한다. 파일열기 파일에서데이터를읽거나쓸수있도록모든준비를마치는것 FILE *fopen(const char *name, const char *mode) 파일열기파일읽기와쓰기파일닫기 첫번째매개변수인 name 은파일의이름 두번째매개변수인 mode 는파일을여는모드를의미 디스크파일은 FILE 구조체를이용하여접근 FILE 구조체를가리키는포인터를파일포인터 (file pointer) FILE *fp; fp = open( test.txt, w ); 9

파일모드 주의할점 모드 r 읽기모드로파일을연다. w a r+ w+ 설명 쓰기모드로파일을생성한다. 만약파일이존재하지않으면파일이생성된다. 파일이이미존재하면기존의내용이지워진다. 추가모드로파일을연다. 만약똑같은이름의기존의파일이있으면데이터가파일의끝에추가된다. 파일이없으면새로운파일을만든다. 읽기모드로파일을연다. 쓰기모드로전환할수있다. 파일이반드시존재하여야한다. 쓰기모드로파일을생성한다. 읽기모드로전환할수있다. 파일이존재하면기존의데이터가지워진다. 기본적인파일모드에 "t" 나 "b" 를붙일수있다. "a" 나 "a+" 모드는추가모드 (append mode) 라고한다. 추가모드로파일이열리면, 모든쓰기동작은파일의끝에서일어난다. 따라서파일안에있었던기존의데이터는절대지워지지않는다. "r+", "w+", "a+" 파일모드가지정되면읽고쓰기가모두가능하다. 이러한모드를수정모드 (update mode) 라고한다. 읽기모드에서쓰기모드로, 또는쓰기모드에서읽기모드로전환하려면반드시 fflush(), fsetpos(), fseek(), rewind() 중의하나를호출하여야한다. a+ 추가모드로파일을연다. 읽기모드로전환할수있다. 데이터를추가하면 EOF 마커를추가된데이터의뒤로이동한다. 파일이없으면새로운파일을만든다. b 이진파일모드로파일을연다. 파일모드 file_open.c FILE *fp = NULL; fp = fopen("sample.txt", "w"); r w a 파일의처음부터읽는다. 파일의처음부터쓴다. 파일의끝에쓴다. 만약파일이존재하면기존파일이없으면생성된다. 의내용이지워진다. if( fp == NULL ) printf(" 파일열기실패 \n"); else printf(" 파일열기성공 \n"); 파일열기성공 10

파일을닫는함수 int fclose( FILE *stream ); 파일을삭제하는함수 int remove(const char *path) 파일닫기와삭제 중간점검 1. 파일은일련의연속된 라고생각할수있다. 2. 파일에는사람이읽을수있는텍스트가들어있는 파일과사람은읽을수없으나컴퓨터는읽을수있는 파일이있다. 3. 파일을여는라이브러리함수는 이다. 4. fopen() 은 을가리키는포인터를반환한다. int main( void ) if( remove( "sample.txt" ) == -1 ) printf( "sample.txt 를삭제할수없습니다.\n" ); else printf( "sample.txt 를삭제하였습니다.\n" ); 파일입출력함수 문자단위입출력 파일입출력라이브러리함수종류설명입력함수출력함수 문자단위문자단위로입출력 int fgetc(file *fp) int fputc(int c, FILE *fp) 문자열단위 서식화된입출력 문자열단위로입출력 char *fgets(file *fp) int fputs(const char *s, FILE *fp) 형식지정입출력 int fscanf(file *fp,...) int fprintf(file *fp,...) 이진데이터이진데이터입출력 fread() fwrite() 크게나누면텍스트입출력함수와이진데이터입출력으로나눌수있습니다. 문자입출력함수 int fgetc( FILE *fp ); int fputc( int c, FILE *fp ); 문자열입출력함수 F I L E char *fgets( char *s, int n, FILE *fp ); int fputs( char *s, FILE *fp ); FILE INPUT 파일포인터 문자열의크기 11

FILE *fp = NULL; 파일열기성공 문자단위입출력 fp = fopen("sample.txt", "w"); if( fp == NULL ) printf(" 파일열기실패 \n"); else printf(" 파일열기성공 \n"); fputc('a', fp); fputc('b', fp); fputc('c', fp); sample.txt abc FILE *fp = NULL; int c; fp = fopen("sample.txt", "r"); if( fp == NULL ) printf(" 파일열기실패 \n"); else printf(" 파일열기성공 \n"); while((c = fgetc(fp))!= EOF ) putchar(c); 파일열기성공 abc 문자단위입출력 sample.txt abc #include <stdlib.h> FILE *fp1, *fp2; char file1[100], file2[100]; char buffer[100]; printf(" 원본파일이름 : "); scanf("%s", file1); printf(" 복사파일이름 : "); scanf("%s", file2); 문자열단위입출력 // 첫번째파일을읽기모드로연다. if( (fp1 = fopen(file1, "r")) == NULL ) fprintf(stderr," 원본파일 %s을열수없습니다.\n", file1); 문자열단위입출력 // 두번째파일을쓰기모드로연다. if( (fp2 = fopen(file2, "w")) == NULL ) fprintf(stderr," 복사파일 %s 을열수없습니다.\n", file2); // 첫번째파일을두번째파일로복사한다. while( fgets(buffer, 100, fp1)!= NULL ) fputs(buffer, fp2); fclose(fp1); fclose(fp2); 원본파일이름 : a.txt 복사파일이름 : b.txt 12

proverb.txt #include <string.h> FILE *fp; char fname[128]; char buffer[256]; char word[256]; int line_num = 0; printf(" 입력파일이름을입력하시오 : "); scanf("%s", fname); printf(" 탐색할단어를입력하시오 : "); scanf("%s", word); A chain is only as strong as its weakest link A change is as good as a rest A fool and his money are soon parted A friend in need is a friend indeed A good beginning makes a good ending A little knowledge is a dangerous thing 2012 생능출판사 All rights reserved // 파일을읽기모드로연다. if( (fp = fopen(fname, "r")) == NULL ) fprintf(stderr," 파일 %s 을열수없습니다.\n", fname); while( fgets(buffer, 256, fp) ) line_num++; if( strstr(buffer, word) ) printf("%s: %d 단어 %s 이발견되었습니다.\n", fname, line_num, word ); 입력파일이름을입력하시오 : proverb.txt 탐색할단어를입력하시오 : house proverb.txt: 7 단어 house 이발견되었습니다. proverb.txt: 8 단어 house 이발견되었습니다. 형식화된출력 int fprintf( FILE *fp, const char *format,...); 형식화된입력 int fscanf( FILE *fp, const char *format,...); int i = 23; float f = 1.2345; FILE *fp; int i; float f; FILE *fp; 100 12.345 fp = fopen("sample.txt", "w"); if( fp!= NULL ) fprintf(fp, "%10d %16.3f", i, f); %d 와같은특정한형식을지정하여파일에출력할수있습니다. fp = fopen("sample.txt", "r"); if( fp!= NULL ) fscanf(fp, "%d %f", &i, &f); printf( %d %f, i, f); fclose(fp): %d 와같은특정한형식을지정하여파일에입력할수있습니다. 13

FILE *fp; char fname[100]; int number, count = 0; char name[20]; float score, total = 0.0; printf(" 성적파일이름을입력하시오 : "); scanf("%s", fname); // 성적파일을쓰기모드로연다. if( (fp = fopen(fname, "w")) == NULL ) fprintf(stderr," 성적파일 %s 을열수없습니다.\n", fname); // 사용자로부터학번, 이름, 성적을입력받아서파일에저장한다. while( 1 ) printf(" 학번, 이름, 성적을입력하시요 : ( 음수이면종료 )"); scanf("%d", &number); if( number < 0 ) break scanf("%s %f", name, &score); fprintf(fp, " %d %s %f", number, name, score); // 성적파일을읽기모드로연다. if( (fp = fopen(fname, "r")) == NULL ) fprintf(stderr," 성적파일 %s 을열수없습니다.\n", fname); // 파일에서성적을읽어서평균을구한다. while(!feof( fp ) ) fscanf(fp, "%d %s %f", &number, name, &score); total += score; count++; printf(" 평균 = %f\n", total/count); 중간점검 1. fgetc() 의반환형은 형이다. 2. 파일에서하나의라인을읽어서반환하는함수는 이다. 3. 텍스트파일에실수나정수를문자열로변경하여저장할때사용하는함수는 이다. 4. 텍스트파일에서실수나정수를읽는함수는 이다. 성적파일이름을입력하시오 : score.txt 학번, 이름, 성적을입력하시요 : ( 음수이면종료 ) 1 KIM 90.2 학번, 이름, 성적을입력하시요 : ( 음수이면종료 ) 2 PARK 30.5 학번, 이름, 성적을입력하시요 : ( 음수이면종료 ) 3 MIN 56.8 학번, 이름, 성적을입력하시요 : ( 음수이면종료 )-1 평균 = 59.166668 14

이진파일쓰기와읽기 이진파일의생성 텍스트파일과이진파일의차이점 텍스트파일 : 모든데이터가아스키코드로변환되어서저장됨 이진파일 : 컴퓨터에서데이터를표현하는방식그대로저장 정수 123456 텍스트파일 1 2 3 4 5 6 00110001 00110010 00110011 00110100 00110101 00110110 이진파일 00000000 00000001 11100010 01000000 rb" wb" ab" rb+" "wb+" 파일모드 FILE *fp = NULL; fp = fopen("binary.txt", "rb"); 읽기모드 + 이진파일모드 쓰기모드 + 이진파일모드 추가모드 + 이진파일모드 읽고쓰기모드 + 이진파일모드 쓰고읽기모드 + 이진파일모드 if( fp == NULL ) printf(" 이진파일열기에실패하였습니다.\n"); else printf(" 이진파일열기에성공하였습니다.\n"); if( fp!= NULL ) 설명 이진파일쓰기 이진파일쓰기 size_t fwrite( void *buffer, size_t size, size_t count, FILE *fp); int buffer[] = 10, 20, 30, 40, 50 ; FILE *fp = NULL; size_t i, size, count; fp = fopen("binary.bin", "wb"); buffer if( fp == NULL ) fprintf(stderr, "binary.txt 파일을열수없습니다."); 항목 count size size = sizeof(buffer[0]); count = sizeof(buffer) / sizeof(buffer[0]); i = fwrite(&buffer, size, count, fp); 15

이진파일읽기 이진파일읽기 size_t fread( void *buffer, size_t size, size_t count, FILE *fp ); #define SIZE 1000 count float buffer[size]; FILE *fp = NULL; size_t size; 항목 buffer size fp = fopen("binary.txt", "rb"); if( fp == NULL ) fprintf(stderr, "binary.txt 파일을열수없습니다."); size = fread( &buffer, sizeof(float), SIZE, fp); if( size!= SIZE ) fprintf(stderr, " 읽기동작중오류가발생했습니다.\n"); 버퍼링 fopen() 을사용하여파일을열면, 버퍼가자동으로만들어진다. 버퍼는파일로부터읽고쓰는데이터의임시저장장소로이용되는메모리의블록 디스크드라이브는블록단위장치이기때문에블록단위로입출력을해야만가장효율적으로동작 1024 바이트의블록이일반적 파일과연결된버퍼는파일과물리적인디스크사이의인터페이스로사용 버퍼링 fflush(fp); 버퍼의내용이디스크파일에써진다. setbuf(fp, NULL); setbuf() 는스트림의버퍼를직접지정하는함수로서만약버퍼자리에 NULL 을써주면버퍼를제거하겠다는것을의미한다. 디스크 버퍼 파일 16

#define SIZE 3 struct student int number; char name[20]; double gpa; ; // 이름 // 학번 // 평점 struct student table[size] = 1, "Kim", 3.99, 2, "Min", 2.68, 3, "Lee", 4.01 ; struct student s; FILE *fp = NULL; int i; // 이진파일을쓰기모드로연다. if( (fp = fopen("student.dat", "wb")) == NULL ) fprintf(stderr," 출력을위한파일을열수없습니다.\n"); // 배열을파일에저장한다. fwrite(table, sizeof(struct student), SIZE, fp); // 이진파일을읽기모드로연다. if( (fp = fopen("student.dat", "rb")) == NULL ) fprintf(stderr," 입력을위한파일을열수없습니다.\n"); for(i = 0;i < SIZE; i++) fread(&s, sizeof(struct student), 1, fp); printf(" 학번 = %d, 이름 = %s, 평점 = %f\n", s.number, s.name, s.gpa); 학번 = 1, 이름 = Kim, 평점 = 3.990000 학번 = 2, 이름 = Min, 평점 = 2.680000 학번 = 3, 이름 = Lee, 평점 = 4.010000 #include <stdlib.h> FILE *fp1, *fp2; char file1[100], file2[100]; char buffer[1024]; int count; printf(" 첫번째파일이름 : "); scanf("%s", file1); printf(" 두번째파일이름 : "); scanf("%s", file2); // 첫번째파일을쓰기모드로연다. if( (fp1 = fopen(file1, "rb")) == NULL ) fprintf(stderr," 입력을위한파일을열수없습니다.\n"); // 두번째파일을추가모드로연다. if( (fp2 = fopen(file2, "ab")) == NULL ) fprintf(stderr," 추가를위한파일을열수없습니다.\n"); // 첫번째파일을두번째파일끝에추가한다. while((count = fread(buffer, sizeof(char), 1024, fp1)) > 0) fwrite(buffer, sizeof(char), count, fp2); fclose(fp1); fclose(fp2); 첫번째파일이름 : a.dat 두번째파일이름 : b.dat 17

다음과같이이진파일의내용을 16 진수로표시하는프로그램을작성하여보자. 흔히이런형식의화면은디버거에서볼수있다. 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 3C 68 33 3E 0D Log</h1>..<h3>. 00000030: 0A 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D.--------------- #include <ctype.h> #include <stdlib.h> FILE *fp; char fname[100]; unsigned char buffer[16]; int address = 0; int i, bytes; printf(" 원본파일이름 : "); scanf("%s", fname); if( (fp = fopen(fname, "rb")) == NULL ) fprintf(stderr," 원본파일 %s 을열수없습니다.\n", fname); 임의접근파일 while(1) bytes = fread(buffer, 1, 16, fp); if( bytes <= 0 ) break; printf("%08x: ", address); for(i = 0; i < bytes; i++) printf("%02x ", buffer[i]); for(i = 0; i < bytes; i++) if( isprint(buffer[i]) ) putchar(buffer[i]); else putchar('.'); address += bytes; putchar('\n'); 순차접근 (sequential access) 방법 : 데이터를파일의처음부터순차적으로읽거나기록하는방법 임의접근 (random access) 방법 : 파일의어느위치에서든지읽기와쓰기가가능한방법 순차접근파일 임의접근파일 18

임의접근파일의원리 임의접근관련함수 파일위치표시자 : 읽기와쓰기동작이현재어떤위치에서이루어지는지를나타낸다. 파일위치표시자 강제적으로파일위치표시자를이동시키면임의접근이가능 int fseek(file *fp, long offset, int origin); 상수 값 설명 SEEK_SET 0 파일의시작 SEEK_CUR 1 현재위치 SEEK_END 2 파일의끝 fseek(fp, 0L, SEEK_SET); // 파일의처음으로이동 fseek(fp, 0L, SEEK_END); // 파일의끝으로이동 fseek(fp, 100L, SEEK_SET); // 파일의처음에서 100바이트이동 fseek(fp, 50L, SEEK_CUR); // 현재위치에서 50바이트이동 fseek(fp, -20L, SEEK_END); // 파일의끝에서 20바이트앞으로이동 fseek(fp, sizeof(struct element), SEEK_SET); // 구조체만큼앞으로이동 void rewind(file *fp); 임의접근관련함수 파일위치표시자를 0 으로초기화 #include <stdlib.h> #define SIZE 1000 void init_table(int table[], int size); long ftell(file *fp); 파일위치표시자의현재위치를반환 파일위치표시자를초기화하고현재위치를알아내는함수들입니다. int table[size]; int n, data; long pos; FILE *fp = NULL; // 배열을초기화한다. init_table(table, SIZE); // 이진파일을쓰기모드로연다. if( (fp = fopen("sample.dat", "wb")) == NULL ) fprintf(stderr," 출력을위한파일을열수없습니다.\n"); 19

// 배열을이진모드로파일에저장한다. fwrite(table, sizeof(int), SIZE, fp); // 이진파일을읽기모드로연다. if( (fp = fopen("sample.dat", "rb")) == NULL ) fprintf(stderr," 입력을위한파일을열수없습니다.\n"); // 사용자가선택한위치의정수를파일로부터읽는다. while(1) printf(" 파일에서의위치를입력하십시요 (0에서 %d, 종료-1): ", SIZE - 1); scanf("%d", &n); if( n == -1 ) break pos = (long) n * sizeof(int); fseek(fp, pos, SEEK_SET); fread(&data, sizeof(int), 1, fp); printf("%d 위치의값은 %d입니다.\n", n, data); // 배열을인덱스의제곱으로채운다. void init_table(int table[], int size) int i; for(i = 0; i < size; i++) table[i] = i * i; 파일에서의위치를입력하십시요 (0 에서 999, 종료 -1): 3 3 위치의값은 9 입니다. 파일에서의위치를입력하십시요 (0 에서 999, 종료 -1): 9 9 위치의값은 81 입니다. 파일에서의위치를입력하십시요 (0 에서 999, 종료 -1): -1 중간점검 1. 파일의처음부터순차적으로읽거나쓰는방법을 이라고한다. 2. 파일의어느위치에서나읽고쓰기가가능한방법을 이라고한다. 3. 파일에서읽기나쓰기가수행되면파일의현재의위치를표시하는 가갱신된다. 4. 파일의위치표시자를알아내는함수는 이다. 실습 : 주소록만들기 자신과친한사람들의정보를저장하고업데이트할수있는간단한프로그램을작성하여보자. 입력하거나업데이트한데이터는파일로저장된다. 저장된데이터에대하여검색할수있다. 자기에게필요한여러가지사항들을저장할수있도록하자. 즉자신만의간단한데이터베이스시스템을작성하여보자. 20

실행결과 힌트 ===================== 1. 추가 2. 수정 3. 검색 4. 종료 ===================== 메뉴를선택하세요 : 1 이름 : 홍길동주소 : 서울시종로구 1 번지휴대폰 : 010-123-4567 특징 : 싸움을잘함, 변신에능함... 파일모드를어떻게해야할까? 적합한것은 a+" 모드이다. 주로추가, 탐색할예정 파일에서읽기전에무조건 fseek() 를해주어야한다. 수정할때는차라리새로운파일을생성하여서거기에전체를다시기록하는것이낫다. #include <string.h> #define SIZE 100 typedef struct person // 연락처를구조체로표현한다. char name[size]; // 이름 char address[size]; // 주소 char mobilephone[size]; // 휴대폰 char desc[size]; // 특징 PERSON; void menu(); PERSON get_record(); void print_record(person data); void add_record(file *fp); void search_record(file *fp); void update_record(file *fp); FILE *fp; int select; // 이진파일을추가모드로오픈한다. if( (fp = fopen("address.dat", "a+")) == NULL ) fprintf(stderr," 입력을위한파일을열수없습니다 ); while(1) menu(); // 메뉴를표시한다 printf(" 정수값을입력하시오 : "); // 사용자로부터정수를받는다 scanf("%d",&select); switch(select) case 1: add_record(fp); break;// 데이터를추가한다 case 2: update_record(fp); break; // 데이터를수정한다 case 3: search_record(fp); break; // 데이터를탐색한다 case 4: // 이진파일을닫는다 21

// 사용자로부터데이터를받아서구조체로반환한다 PERSON get_record() PERSON data; fflush(stdin); // 표준입력의버퍼를비운다 printf(" 이름 ); gets(data.name); // 이름을입력받는다 printf(" 주소 ); gets(data.address); // 주소를입력받는다 printf(" 휴대폰 ); gets(data.mobilephone); // 휴대폰번호를 입력받는다 printf(" 특징 ); gets(data.desc); // 특징을입력받는다 return data; // 구조체데이터를화면에출력한다. void print_record(person data) printf(" 이름 \n", data.name); printf(" 주소 \n", data.address); printf(" 휴대폰 \n", data.mobilephone); printf(" 특징 \n", data.desc); // 메뉴를화면에표시하는함수 void menu() printf("====================\n"); printf(" 1. 추가 \n 2. 수정 \n 3. 검색 \n 4. 종료 \n"); printf("====================\n"); // 데이터를추가한다 void add_record(file *fp) PERSON data; data = get_record(); // 사용자로부터데이터를받아서구조체에저장 fseek(fp, 0, SEEK_END); // 파일의끝으로간다 fwrite(&data, sizeof(data), 1, fp);// 구조체데이터를파일에쓴다 // 데이터를탐색한다 void search_record(file *fp) char name[size]; PERSON data; fseek(fp, 0, SEEK_SET); // 파일의처음으로간다 fflush(stdin); printf(" 탐색하고자하는사람의이름 "); gets(name); // 이름을입력받는다 while(!feof(fp)) // 파일의끝까지반복한다 fread(&data, sizeof(data), 1, fp); // 현재위치에서데이터를읽는다 if( strcmp(data.name, name) == 0 ) // 이름을비교한다 print_record(data); // 일치하면데이터를화면에출력한다 break; // 데이터를수정한다 void update_record(file *fp) //... 도전문제 search_record() 에서탐색이실패했으면에러메시지를출력하도록코드를추가하여보라. update_record() 함수를구현하여보자. 앞에서언급한대로수정된부분만파일에덮어쓰는것은상당히어렵다. 따라서수정된전체내용을읽어서새로운파일에쓰도록해보자. 22

Q & A 23