Transcript 13장

13장. 입출력 라이브러리
#include <stdio.h>
int main(void)
{
int num;
printf(“Please enter an integer: ");
scanf("%d", &num);
if ( num < 0 )
printf("Is negative.\n");
printf("num = %d\n", num);
return 0;
}
1
표준 입출력
 스트림 기반의 입출력
스트림 :연속된 데이터 바이트의 흐름
프로그램의 입출력(I/O)
프로그램이 프로그램의 외부와 상호작용을 하는 것
장치 독립성(device independence) : 입출력 장치의 종류에 관계없이 동일한 방
법으로 입출력을 수행한다.
13장. 입출력 라이브러리
2
표준 입출력
 스트림 기반의 입출력
버퍼를 경유한 입출력
표준 C 입출력 라이브러리에서는 입력 스트림의 내부에 버퍼를 두고, 키보드로부
터 입력된 내용을 임시로 버퍼에 저장했다가 특정 시점에 프로그램으로 한 번에
전달한다.
입력 장치와 CPU의 처리 속도 차에도 불구하고 효율적인 입출력이 가능하다.
13장. 입출력 라이브러리
3
표준 입출력
 스트림 기반의 입출력
표준 입출력 스트림
표준 C 입출력 라이브러리는 표준 입출력 스트림을 제공한다.
표준 입출력을 수행하기 위한 기본적인 스트림을 프로그램 시작 시 생성하고, 프
로그램 종료 시 해제한다.
stdin, stdout, stderr가 바로 표준 입출력 스트림이다.
13장. 입출력 라이브러리
4
표준 입출력
 printf 함수 다시 보기
printf 함수의 원형
printf 함수의 형식 문자열의 구조
13장. 입출력 라이브러리
5
표준 입출력
 printf 함수 다시 보기
type 필드 : 출력할 값의 형식을 지정
type 필드 앞에 h, l, L 지정
h : short형을 출력
l : long형을 출력
ex. %hd는 short형을 10진수
정수로 출력
ex. %ld는 long형을 10진수 정
수로 출력
L : 실수형 중 long double형을
출력
13장. 입출력 라이브러리
6
표준 입출력
 printf 함수 다시 보기
width 필드 : 출력하는 값의 폭을 지정
출력의 폭을 지정하면 전체 폭의 오른쪽에 맞춰서 출력한다.
실수를 출력할 때는 소수점 이하 6자리를 기본적으로 출력한다.
13장. 입출력 라이브러리
7
표준 입출력
 printf 함수 다시 보기
precision 필드 : 출력하는 값의 정밀도를 지정
정밀도보다 출력할 정수의 개수가 적으면 0으로 채워서 출력한다.
실수 출력에 정밀도를 지정하면, 소수점 이하 자리수의 개수를 의미한다.
13장. 입출력 라이브러리
8
표준 입출력
 printf 함수 다시 보기
flags 필드 : -, +, O, 빈칸, # 문자가 올 수 있다.
13장. 입출력 라이브러리
9
표준 입출력
 scanf 함수 다시 보기
scanf 함수의 원형
scanf 함수의 형식 문자열의 구조
13장. 입출력 라이브러리
10
표준 입출력
 scanf 함수 다시 보기
type 필드
문자 입력 : %c
정수 입력 : %d, %i, %u, %o, %x, %X
실수 입력 : %e, %E, %f, %g, %G
문자열 입력 : %s
13장. 입출력 라이브러리
11
표준 입출력
 scanf 함수 다시 보기
width 필드 : 입력 받을 값의 폭을 지정
입력받을 값의 자릿수를 지정한다.
width 필드를 지정하면 공백 문자로 구분하지 않고도 여러 값을 입력할 수 있다.
*는 현재 입력을 무시하라는 의미이다.
13장. 입출력 라이브러리
12
표준 입출력
 scanf 함수 다시 보기
scanf 함수의 형식 문자열 사용 예
13장. 입출력 라이브러리
13
표준 입출력
 scanf 함수 다시 보기
scanf 함수를 이용한 입력 시 에러 처리
scanf 함수의 리턴 값 : 정상적으로 입력된 항목의 개수
여러 개의 항목을 입력 받을 때는 전체 항목의 개수를 확인한다.
13장. 입출력 라이브러리
14
표준 입출력
 scanf 함수 다시 보기
입력에 대한 에러 처리 예(1/4)
01:
02:
03:
04:
05:
06:
07:
08:
09:
10:
11:
12:
13:
14:
15:
16:
17:
18:
/* Ex13_01.c */
#include <stdio.h>
int main(void)
{
int a, b;
char op;
while ( 1 )
{
printf("수식을 입력하세요 (0 0 0 입력시 종료) : ");
if( scanf("%d %c %d", &a, &op, &b) < 3 )
{
printf("잘못 입력하셨습니다.\n"
"<정수> <연산자> <정수>의 순으로 입력하세요.\n");
continue;
}
13장. 입출력 라이브러리
입력에 대한
에러 처리
15
표준 입출력
 scanf 함수 다시 보기
입력에 대한 에러 처리 예(2/4)
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
if( a == 0 && op == '0' && b == 0 )
break;
switch ( op )
{
case '+':
printf("%d + %d = %d\n", a, b, a + b);
break;
case '-':
printf("%d - %d = %d\n", a, b, a - b);
break;
case '*':
printf("%d * %d = %d\n", a, b, a * b);
break;
case '/':
printf("%d / %d = %d\n", a, b, a / b);
break;
default:
printf("잘못된 연산자입니다.\n");
continue;
}
13장. 입출력 라이브러리
16
표준 입출력
 scanf 함수 다시 보기
입력에 대한 에러 처리 예(3/4)
39:
40:
41:
42:
43: }
}
return 0;
입력 버퍼에 들어 있는
“a b c”는 사용되지 않
았으므로 계속 입력 버
퍼에 남아있게 된다.
13장. 입출력 라이브러리
17
표준 입출력
 scanf 함수 다시 보기
입력에 대한 에러 처리 예(4/4)
13장. 입출력 라이브러리
18
표준 입출력
 scanf 함수 다시 보기
ffush 함수 : 입력 버퍼를 강제로 비울 때 사용
13장. 입출력 라이브러리
19
표준 입출력
 그 밖의 표준 입출력 함수
그 밖의 표준 입출력 함수
13장. 입출력 라이브러리
20
표준 입출력
 그 밖의 표준 입출력 함수
표준 입출력 함수와 파일 입출력 함수
스트림 방식의 입출력 라이브러리는 입출력 장치에 관계없이 동일한 방식으로 입
출력을 처리할 수 있다.
키보드 입력과 파일 입력, 콘솔 출력과 파일 출력을 동일하게 처리할 수 있다.
표준 C 입출력 라이브러리는 표준 입출력 함수를 파일 입출력 함수와는 별도로
제공한다.
콘솔 출력에는 printf 함수를 사용하고, 파일 출력에는 fprintf 함수를 사용한다.
언제든지 표준 입출력 함수 대신 파일 입출력 함수를 이용해서 표준 입출력을 처
리할 수 있다.
13장. 입출력 라이브러리
21
파일 입출력
 파일 입출력의 개요
파일 입출력의 개요(1/2)
파일 입출력을 할 때는, 먼저 스트림을 생성한 다음에 입출력을 수행해야 함
Fopen 함수로 파일을 열면 파일 포인터 리턴
파일에 접근하려면 항상 파일 포인터 필요
일단 파일을 연 다음에는 여러 가지 파일 입출력 함수를 이용해서 입출력 작업
수행
텍스트 파일 입출력 : fgetc, fputc, fgets, fputs, fscanf, fprintf
바이너리 파일 입출력 : fread, fwrite
모든 입출력이 끝나면 파일을 닫아야 함
파일을 닫을 때 fclose 함수를 사용
13장. 입출력 라이브러리
22
파일 입출력
 파일 입출력의 개요
파일 입출력의 개요(2/2)
13장. 입출력 라이브러리
23
파일 입출력
 파일 입출력의 개요
파일 열기(1/2)
파일 입출력을 수행하려면 우선 fopen 함수를 호출해서 파일을 열어야 함
Fopen 함수의 원형
Filename : 파일 이름
Mode : 파일 열기 모드
리턴 값 : 생성된 파일 스트림의 파일 포인터 리턴.
파일을 열 수 없으면 널 포인터를 리턴.
기본적으로 파일을 텍스트 파일로 간주
13장. 입출력 라이브러리
24
파일 입출력
 파일 입출력의 개요
파일 열기(2/2)
파일 열기 모드
13장. 입출력 라이브러리
25
파일 입출력
 파일 입출력의 개요
파일 닫기
파일 입출력이 끝나면 fclose 함수를 호출해서 반드시 파일을 닫아야 함
Fclose 함수의 원형
Stream : 파일 포인터
리턴 값 : 파일 닫기가 성공하면 0을 리턴하고, 실패하면 EOF(-1)을 리턴
13장. 입출력 라이브러리
26
파일 입출력
 파일 입출력의 개요
ferror 함수
파일 입출력 시 발생하는 에러 확인
리턴 값 : 스트림에 에러가 발생했으면 0을 이 아닌 값을 리턴
에러가 발생하지 않았으면 0을 리턴
feof 함수
파일의 끝인지를 검사한다.
리턴 값 : 읽은 위치가 파일의 끝이면 0이 아닌 값을 리턴하고, 그렇지 않으면 0 리턴
13장. 입출력 라이브러리
27
파일 입출력
 텍스트 파일 입출력
텍스트 파일 입출력 함수
13장. 입출력 라이브러리
28
파일 입출력
 텍스트 파일 입출력
fgetc, fputc
파일로부터 문자 하나를 입력 받거나 출력할 때 사용.
13장. 입출력 라이브러리
29
파일 입출력
 텍스트 파일 입출력
fgetc, fputc를 이용한 텍스트 파일 복사(1/2)
01:
02:
03:
04:
05:
06:
07:
08:
09:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
/* Ex13_02.c */
#include <stdio.h>
int main(int argc, char *argv[ ])
{
FILE *fp1, *fp2;
char ch;
파일 포인터 변수 선언
if( argc < 3 )
{
printf("Usage: FCopy src_file dest_file\n");
return -1;
}
입력용 파일 열기
fp1 = fopen(argv[1], "r");
if( fp1 == NULL )
{
printf("%s 파일 열기 실패\n", argv[1]);
return -1;
}
13장. 입출력 라이브러리
30
파일 입출력
 텍스트 파일 입출력
fgetc, fputc를 이용한 텍스트 파일 복사(2/2)
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36: }
출력용 파일 열기
fp2 = fopen(argv[2], "w");
if( fp2 == NULL )
{
printf("%s 파일 열기 실패\n", argv[2]);
return -1;
}
while( (ch = fgetc(fp1)) != EOF )
fputc(ch, fp2);
fclose(fp1);
fclose(fp2);
return 0;
테스트 파일 복사
파일 닫기
a.txt 파일을 먼저 생성한 다음
명령 프롬프트에 “fcopy.exe a.txt b.txt”
로 실행하면 b.txt 파일이 생성된다.
13장. 입출력 라이브러리
31
파일 입출력
 텍스트 파일 입출력
fgets, fputs
파일로부터 한 줄의 문자열을 입력 받거나 출력할 때 사용
fgets
str : 읽은 문자열을 저장할 문자 배열의 주소
n : 문자 배열의 크기
stream : 입력용 파일 포인터
리턴 값 : 파일로부터 문자열을 최대 n-1개만큼(또는 줄바꿈 문자까지) 읽어서 str에 저
장한다. 에러를 만나거나 EOF를 만나면 NULL을 리턴한다.
fputs
str : 저장할 문자열
fp : 출력용 파일 포인터
리턴 값 : 저장한 문자수
13장. 입출력 라이브러리
32
파일 입출력
 텍스트 파일 입출력
fgets, fputs를 이용한 텍스트 파일 복사(1/2)
01:
02:
03:
04:
05:
06:
07:
08:
09:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
/* Ex13_03.c */
#include <stdio.h>
#define MAX_BUF 100
int main(int argc, char *argv[ ])
{
FILE *fp1, *fp2;
char buffer[MAX_BUF];
문자 배열 선언
if( argc < 3 )
{
printf("Usage: FCopy src_file dest_file\n");
return -1;
}
fp1 = fopen(argv[1], "r");
if( fp1 == NULL )
{
13장. 입출력 라이브러리
33
파일 입출력
 텍스트 파일 입출력
fgets, fputs를 이용한 텍스트 파일 복사(2/2)
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38: }
}
printf("%s 파일 열기 실패\n", argv[1]);
return -1;
fp2 = fopen(argv[2], "w");
if( fp2 == NULL )
{
printf("%s 파일 열기 실패\n", argv[2]);
return -1;
}
한 번에 char[100]만큼씩 파일을 읽고 쓰
기 때문에 파일 입출력의 횟수가 훨씬 적
다. 파일 입출력 시 적은 양의 데이터를
여러 번 입출력을 하는 것보다는 한 번에
많은 양의 데이터를 입출력하는 것이 더
효율적이다.
while( fgets(buffer, MAX_BUF, fp1) != NULL )
fputs(buffer, fp2);
한 줄씩 문자열 복사
fclose(fp1);
fclose(fp2);
return 0;
13장. 입출력 라이브러리
34
파일 입출력
 텍스트 파일 입출력
fscanf, fprintf
형식화된 문자열을 파일로 입출력할 때는 사용
stream : 파일 포인터
나머지 매개변수는 scanf, printf 함수와 동일
13장. 입출력 라이브러리
35
파일 입출력
 텍스트 파일 입출력
성적에 대한 보고서를 생성하는 예제(1/3)
01:
02:
03:
04:
05:
06:
07:
08:
09:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
/* Ex13_04.c */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_STUDENT 5
typedef struct student {
char name[20];
int korean, english, math;
double average;
} STUDENT;
int main( )
{
STUDENT std[MAX_STUDENT];
int i;
FILE *fp = NULL;
13장. 입출력 라이브러리
36
파일 입출력
 텍스트 파일 입출력
성적에 대한 보고서를 생성하는 예제(2/3)
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
for( i = 0 ; i < MAX_STUDENT ; i++ )
{
printf("학생 정보를 입력하세요 : ");
scanf("%s %d %d %d", std[i].name,
&std[i].korean, &std[i].english, &std[i].math);
std[i].average = (double) (std[i].korean
+ std[i].english + std[i].math)/3;
}
fp = fopen("report.txt", "w");
if( fp == NULL )
{
printf("파일 열기 실패\n");
return -1;
}
텍스트 파일 열기
13장. 입출력 라이브러리
37
파일 입출력
 텍스트 파일 입출력
성적에 대한 보고서를 생성하는 예제(3/3)
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46: }
for( i = 0 ; i < MAX_STUDENT ; i++ )
{
fprintf(fp, "%-10s %3d %3d %3d %6.2f\n", std[i].name,
std[i].korean, std[i].english, std[i].math,
std[i].average);
}
fclose(fp);
텍스트 파일 닫기
return 0;
프로그램 실행 결과
로 생성된 파일
report.txt
김모모
박나나
이만수
최하나
한사랑
텍스트 파일로 출력
100
90
60
80
70
100
90
30
90
80
100
90
50
70
90
100.00
90.00
46.67
80.00
80.00
13장. 입출력 라이브러리
38
파일 입출력
 바이너리 파일 입출력
바이너리 파일 입출력 함수
13장. 입출력 라이브러리
39
파일 입출력
 바이너리 파일 입출력
fwrite 함수
파일로 바이너리 데이터를 저장한다.
fwrite 함수의 원형
buffer : 파일로 저장할 데이터의 주소
– buffer는 배열의 시작 주소가 될 수도 있고, 기본형 변수나 구조체 변수의 주소가 될 수
도 있다.
size : 저장할 데이터 항목 하나의 바이트 크기
count : 저장할 항목의 개수
stream : 파일 포인터이다.
리턴 값 : 저장한 항목의 개수
13장. 입출력 라이브러리
40
파일 입출력
 바이너리 파일 입출력
fread 함수
파일에서 바이너리 데이터를 읽어온다.
fread 함수의 원형
buffer : 파일로 저장할 데이터의 주소
– buffer는 배열의 시작 주소가 될 수도 있고, 기본형 변수나 구조체 변수의 주소가
될 수도 있다.
size : 저장할 데이터 항목 하나의 바이트 크기
count : 저장할 항목의 개수
stream : 파일 포인터이다.
리턴 값 : 저장한 항목의 개수
13장. 입출력 라이브러리
41
파일 입출력
 바이너리 파일 입출력
바이너리 파일의 입출력 예제(1/2)
01:
02:
03:
04:
05:
06:
07:
08:
09:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int arr1[10] = { 34, 90, 87, 65, 46, 21, 19, 53, 78, 2 };
int arr2[10];
int i;
FILE *fp;
fp = fopen("test.dat", "wb");
if( fp == NULL )
{
printf("파일 열기 실패\n");
return -1;
}
fwrite(arr1, sizeof(int), 10, fp);
fclose(fp);
출력용 바이너리 파일 열기
바이너리 파일로
정수형 배열 저장
13장. 입출력 라이브러리
42
파일 입출력
 바이너리 파일 입출력
바이너리 파일의 입출력 예제(2/2)
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36: }
fp = fopen("test.dat", "rb");
if( fp == NULL )
{
printf("파일 열기 실패\n");
return -1;
}
fread(arr2, sizeof(int), 10, fp);
fclose(fp);
입력용바이너리 파일 열기
바이너리 파일로
정수형 배열 읽기
for( i = 0 ; i < 10 ; i++ )
printf("%d ", arr2[i]);
printf("\n");
return 0;
13장. 입출력 라이브러리
43
파일 입출력
 바이너리 파일 입출력
fseek, ftell
파일의 임의 접근에 사용된다.
fseek 함수 : 파일에서 입출력을 수행할 위치를 조정한다.
ftell 함수 : 파일의 입출력 위치를 리턴한다.
13장. 입출력 라이브러리
44
학습정리
표준 입출력
스트림 기반의 입출력 : 연속된 데이터 바이트의 흐름을 스트림이라고 한다. 스트
림을 이용하면 입출력 장치의 종류에 관계없이 동일한 방법으로 입출력을 수행할
수 있다.
printf 함수 : printf 함수의 형식 문자열의 구조는 다음과 같다.
%[flags] [width] [.precision] [{h | l | L}]type
scanf 함수 : scanf 함수의 형식 문자열의 구조는 다음과 같다.
%[*] [width] [{h | l | L}]type
scanf 함수의 리턴 값을 이용하면 입력 시 에러 처리를 구현할 수 있다.
그 밖의 표준 입출력 함수
13장. 입출력 라이브러리
45
학습정리
파일 입출력
파일 열기와 파일 닫기 : 파일 열기에는 fopen 함수를 이용하고, 파일 닫기에는
fclose 함수를 이용한다.
FILE *fopen(const char *filename, const char *mode);
int fclose(FILE *stream);
텍스트 파일 입출력 함수
바이너리 파일 입출력 함수
size_t fread(void *buffer, size_t size, size_t count, FILE *stream);
size_t fwrite(const void *buffer, size_t size, size_t count, FILE *stream);
13장. 입출력 라이브러리
46