[ C 언어 스터디 ]

자료출처 : 핵심 길잡이 C 프로그래밍언어
도서출판 : 성안당


13 파일 입출력 함수


★ 표준 입출력 함수 ★

파일 ( file )은 컴퓨터의 디스크나 데이프와 같은 기억 장치에 어떤 정보들이 모임이
저장된 기억 장소를 말한다. 이때 그 기억 장소의 이름을 파일명 ( file name )이라 한다.
일반적으로 파일은 일반 파일 ( general file ) , 디렉토리 파일 ( directory file ) , 특수 파일
( special file )로 나눌 수 있다. 여기서 우리가 가장 많이 접하게 되는 파일은 일반 파일
이다. 일반 파일은 프로그래머가 서술한 그대로 ASCII 문자들로 구성된 텍스트 파일
( text file )과 , 원시 프로그램을 컴파일하여 만들어진 이진 파일 ( binary file )이 있다.

C 언어에서는 키보드( keyboard ) , 콘솔( console ) , 프린터( printer ) 등의 입 . 출력 장
치를 하나의 파일로 취급한다. 이를 표준 입출력 파일( standard input / output file )이
라 한다. 이들은 프로그램 실행과 동시에 개방( open )되어 사용되고 , 종료와 동시에 자
동으로 닫힌다. 이와 같은 기능은 < stdio.h >라는 헤더 파일 내에 기본적인 입출력 스트
림 ( input / output stream )에 관한 매크로로 정의되어 있다. [ 표 13-1 ]은 표준 입출력
스트림에 관한 매크로를 나타낸 것이다.

스트림명 기 능 파일 식별자

stdin

표준 입력 ( standard input )

0

stdout

표준 출력 ( standard output )

1

stderr

표준 오류 ( standard error )

2

stdaux

표준 보조 장치 ( standard auxiliary )

3

stdprn

표준 프린터 ( standard print )

4


예를 들면

fprintf ( stdout , " The C programming \n " ) ;

이라는 문장이 있을 때 , stdout이 지정된 곳에 " The C programming " 이라는 문자열을
출력하라는 의미이다. 이때 stdout은 파일 포인터가 아닌 표준 출력을 의미한다. 결국
위의 문장은 다음과 동일한 의미가 된다 .

printf ( " The C programming \n " ) ;

다음 프로그램의 실행 결과를 나타내시오

▶ 프로그램
# include < stdio.h >

void main ( void )
{

int a ;

while ( ( a = getc ( stdin ) ) != EOF )
putc ( a , stdout ) ;

}

▶ 실행 결과
seoul   Enter
seoul
Ctrl z   Enter


위 예제는 키보드에서 입력한 문자를 화면 ( 모니터 )으로 출력하는 표준 입출력
프로그램이다. getc ( ) 함수는 문자를 키보드로부터 입력받아서 변수 a 에 대입한다.
변수 a 에 기억된 값이 EOF ( - 1 )와 같지 않으면 putc ( ) 함수를 수행하여 하나의 문자
를 화면으로 출력한다.


★ 고수준 파일 입출력 함수 ★

일반적으로 프로그램은 사용자 파일 ( user file )을 이용하여 입출력을 수행한다. 이때
고수준 입출력 함수들은 파일들이 기억되어 있는 장치들에 직접 데이터를 읽기 / 쓰기
하는 것이 아니라 시스템에서 설정한 입출력 버퍼에 읽기 / 쓰기를 한다.

입력 버퍼의 데이터가 비게 되거나 출력 버퍼가 데이터로 가득 차게 되면 시스템은
자동으로 파일 장치들에 읽기 / 쓰기를 수행하게 된다 이것을 버퍼링 ( buffering ) 이라고
하며 , 이때의 버퍼를 스트림 버퍼 ( stream buffer )라고 한다. 그리고 이때의 파일을 스
트림 파일 ( stream file )이라고 한다.

[ 그림 13-1 ] 고수준 파일 입출력 함수와 버퍼

표준 입출력 파일은 운영 체제가 자동으로 파일을 열고 닫는다. 또한 입출력 버퍼를
설정하고 초기화하여 준다. 그러나 고수준 파일 입출력 함수들이 데이터를 읽기 / 쓰기 하
려면 먼저 파일을 열어 주어야 하며 , 입출력을 위한 버퍼 영역을 초기화하여야 한다.

[ 표 13-2 ]는 헤더 파일 < stdio.h >에 정의되어 있는 표준 입출력에 관련된 라이브러리
함수를 나타낸 것이다.

[ 표 13-2 ] 스트림 입출력 함수

함 수 기 능
fopen ( ) 파일 열기
fclose ( ) 파일 닫기
gets ( ) 표준 입력 장치로부터 한 줄의 내용 읽기
puts ( ) 표준 출력 장치에 한 줄의 내용 출력
getc ( ) 파일로부터 한 문자 읽기
putc ( ) 파일에 한 문자 출력
fgetc ( ) 파일로부터 한 문자 읽기
fputc ( ) 파일에 한 문자 출력
fgets ( ) 파일로부터 문자열 읽기
fputs ( ) 파일에 문자열 출력
fscanf ( ) 파일로부터 지정된 형식으로 데이터 읽기
fprintf ( ) 파일에 지정된 형식으로 데이터 출력
fseek ( ) 주어진 위치로 파일 포인터를 이동
feof ( ) 파일의 끝인지를 판단
ftell ( ) 파일 포인터가 가리키는 파일의 현재 위치 얻기
rewind ( ) 파일 포인터를 파일의 처음 위치로 이동
ferror ( ) 파일 읽기 / 쓰기에 오류 ( error ) 여부를 판단
fread ( ) 파일로부터 지정된 블록만큼 읽기
fwrite ( ) 파일에 지정된 블록만큼 데이터 출력


< 파일 선언 >

파일 입출력을 하기 위해서는 먼저 파일 포인터를 선언하여야 한다. 파일 포인터는
스트림에 존재하게 되는 것으로 , 실제 파일과 프로그램을 연결해 주는 통로가 된다. 이
러한 파일 포인터의 선언 형식은 다음과 같다 .

형 식
FILE *파일포인터변수명

FILE는 스트림의 현재 상태에 관한 정보를 저장하기 위한 구조체 즉 , 모든 스트림
I / O 연산에 사용될 파일과 입출력 버퍼에 관한 정보를 저장하기 위한 구조체를 말한
다. 구조체 FILE는 헤더 파일 < stdio.h >에 다음과 같이 정의되어 있다.

struct _iobuf
{

char *_ptr ;
int _cnt ;
char *_base ;
int _flag ;
int _file ;
int _charbuf ;
int _bufsiz ;
char *_tmpfname ;

} ;
typedef struct _iobuf FILE ;

예를 들어 다음과 같이 선언하면

FILE *fp1 , *fp2 ;

fp1과 fp2는 어떤 파일에 관한 정보가 저장된 기억 장소를 지정하는 포인터 값을 가지
는 파일 포인터 변수가 된다 . 파일 포인터 ( file pointer )란 액세스 ( access )하려는 파일
의 내부 이름을 의미하며 , 그 파일에 관한 정보가 저장된 기억 장소를 지정하는 포인터
를 말한다.


< 파일 열기 : fopen ( ) >

프로그램에서 파일을 읽거나 파일에 어떤 결과를 쓰기 위해서는 그 전에 반드시 파
일이 열려 있어야 한다. fopen ( ) 함수는 파일을 열어 입출력 버퍼를 파일에 할당하고
파일 포인터를 프로그램으로 반환하여 파일 처리에 관련된 입출력 함수들이 이 파일
포인터를 이용할 수 있도록 한다.

fopen ( ) 함수의 형식은 다음과 같다.

형 식
FILE *파일포인터변수명 ;
파일포인터변수명 = fopen ( 파일명 , 파일모드 ) ;

예를 들면

FILE *fp ;
fp = fopen ( " text . dat " , " r " ) ;

여기서 FILE는 stdio.h에 구조체형으로 정의되어 있으며 , 파일과 입출력 버퍼에 관
한 정보가 포함되어 있다 . fp는 파일 포인터로서 접근하려는 파일의 내부 이름으로, 그
파일에 관한 정보가 저장된 기억 장소를 가리키는 포인터이다. 그리고 파일명은 접근하
려는 파일의 이름으로서 문자열로 지정하면 된다.

fopen ( ) 함수는 이와 같이 구조체형 FILE에 대한 포인터를 되돌려 줌으로써 다른
입출력 함수들이 여기에 포함된 정보를 가지고 파일을 처리할 수 있도록 하여 준다.
fopen ( ) 함수는 stdio.h 에 다음과 같이 선언되어 있다.

FILE *fopen ( ) ;

따라서 , 프로그램에서 선언해 줄 필요는 없다. 그러나 fopen ( ) 함수를 수행한 결과값
인 파일 포인터를 기억하기 위해 반드시 파일 포인터를 선언해 주어야 한다 .

만일 파일을 열기 ( open ) 할 수 없으면 fopen ( ) 함수는 NULL 값을 되돌려 준다 .
파일 모드는 파일의 접근 모드를 결정하여 준다 . C 언어의 파일 모드를 나타내면 다음
과 같다 .

[ 표 13-3 ] 파일 모드
종 류 의 미
" r " 파일의 처음부터 읽기만 하기 위해 오픈( open )한다. 이때 파일은 반드시 존재 해야 한다.
" w " 파일의 처음 위치부터 쓰기만 하기 위해 오픈한다. 파일이 존재하지 않으면 새롭게 파일을 생성하고 , 파일이 이미 존재하면 기존의 내용은 무시한다 .
" a " 파일의 끝에 추가 ( append )하기 위해 오픈한다 . 파일이 존재하지 않으면 새롭게 파일을 생성한다.


종 류 의 미
" w+ " 파일 읽기 / 쓰기를 위해 사용되며 , 파일이 존재하지 않으면 새롭게 파일을 생성 하고 , 파일이 존재하면 기존의 내용은 무시한다.
" r+ " 파일 읽기 / 쓰기를 위해 사용되며 , 파일이 존재하지 않으면 에러가 발생한다.
" a+ " 파일의 끝에 읽기 / 쓰기를 위해 사용되며 , 파일이 존재하지 않으면 새롭게 파일을 생성하고 , 파일이 존재하면 파일의 끝에 추가한다.


위에서 '+' 다음에 사용되는 문자가 있는데 형식은 다음과 같다.

● " w+t " 또는 " wt " : 텍스트 모드 ( text mode )로 파일을 오픈한다.
● " w+b " 또는 " wb " : 이진 모드 ( binary mode )로 파일을 오픈한다.

이들 모드들 중 "w" , "r" , "a" 는 주로 순차 파일 ( sequential file )에 사용되며 ,
"w+" , "r+" , "a+"는 랜덤 파일 ( random file )에 사용된다.


< 파일 닫기 : fclose ( ) >

fopen ( ) 함수에 의하여 오픈된 파일을 닫고자 할 때 사용하는 함수이다. 오픈된 파
일은 반드시 닫아 주어야 한다. 만일 닫아 주지 않으면 프로그램이 끝날 때 자동으로
닫힌다.

fclose ( ) 함수의 형식은 다음과 같다.

형 식

fclose ( 파일포인터변수명 ) ;


fclose ( ) 함수는 파일이 성공적으로 닫혔을 경우에는 0( zero ) 값을 되돌려 주고 , 그
렇지 않으면 1을 되돌려 준다.

예를 들면 ,

FILE *fp ;  // 파일 포인터 변수 선언

// 드라이브 A에 test . dat라는 파일을 쓰기 전용으로 오픈
fp = fopen ( " a : test . dat " , "w" ) ;

fclose ( fp ) ;


예제 13 . 2

키보드로부터 입력받은 데이터를 test . dat라는 파일에 출력하는 프로그램이다 . 실행 결과를 나타내시오

▶ 프로그램
# include < stdio.h >

void main ( void )
{

int ch ;

FILE *fp ;  // Turbo C 에서는 *fopen ( )을 선언해야 한다 .
fp = fopen ( " test . dat " , "w" ) ;

while ( ( ch = getchar ( ) ) != EOF )
putc ( ch , fp ) ;

fclose ( fp ) ;

}

▶ 실행 결과
This is a sample file 1
This is a sample file 2
This is a sample file 3
Ctrl z

[ test . dat 의 내용 ]
This is a sample file 1
This is a sample file 2
This is a sample file 3



위 예제의 test . dat 파일의 내용을 sample . dat라는 파일의 뒤에 추가시키는 프로그램
이다. 실행 결과를 나타내시오

▶ 프로그램
# include < stdio.h >

void main ( void )
{

int ch ;
FILE *fp1 , *fp2 ;

if ( ( fp1 = fopen ( " test . dat " , "r" ) ) != NULL )
{

fp2 = fopen ( " sample . dat " , "a" ) ;

while ( ( ch = getc ( fp1 ) ) != EOF )
putc ( ch , fp2 ) ;

fclose ( fp1 ) ;
fclose ( fp2 ) ;

}
else

printf ( " File open error !!! \n " ) ;

}

[ sample . dat의 내용 ]
First line of sample . dat
Second line of sample . dat

▶ 실행 결과 ( 실행 후 sample . dat의 파일의 내용 )

First line of sample . dat
Second line of sample . dat
This is a sample file 1
This is a sample file 2
This is a sample file 3


< getc ( ) , putc ( ) >

1. getc ( ) 함수 ( get character )

getc ( ) 함수는 getchar ( ) 함수와 기능이 유사하다. getchar ( ) 함수가 표준 입력 파
일로부터 하나의 문자를 읽어들이는 데 비하여 , getc ( ) 함수는 파일 포인터로 지정된
파일로부터 하나의 문자를 읽어들인다.

getc ( ) 함수의 일반 형식은 다음과 같다 .

형 식
int getc ( FILE *fp ) ;


getc ( ) 함수는 읽어들인 문자의 코드값을 int 형으로 되돌려 주며 , 파일의 끝이나 오
류가 발생하면 -1을 되돌려 준다 . 오픈된 파일이 이진 파일인 경우에는 파일의 끝을 결
정하는 feof ( ) 함수가 필요하다. 만약 , 키보드로부터 자료를 입력시킬 때에는 다음과
같이 나타낸다 .

getc ( stdin ) ;


< putc ( ) 함수 ( put character ) >

putc ( ) 함수는 putchar ( ) 함수와 기능이 유사하다. putchar ( ) 함수는 표준 출력 파
일에 하나의 문자를 출력하는 데 반하여 , putc ( ) 함수는 파일 포인터로 지정된 파일에
하나의 문자를 출력한다.

putc ( ) 함수의 형식은 다음과 같다.

형 식
int putc ( char ch , FILE *fp ) ;

여기서 변수 ch는 문자형 ( char 형)으로 출력할 문자를 나타낸다 . 만약 에러가 발생하
면 -1을 함수값으로 되돌려 준다 .

한편 , 시스템에서 지정한 표준 입출력 파일은 파일 포인터가 정해져 있다. stdout
은 표준 출력 파일에 대한 파일 포인터이며 , stdin은 표준 입력 파일에 대한 파일 포
인터이다. 이들은 stdio.h에 정의되어 있으며 , 다음과 같은 형태로 getchar ( ) 함수와
putchar ( ) 함수를 매크로로 정의하고 있다.

# define getchar ( ) getc ( stdin )
# define putchar ( ch ) putc ( ch , stdout )

따라서 표준 출력으로 출력시키고자 할 때에는 다음과 같이 하면 된다.

putc ( ch , stdout ) ;

다음 프로그램의 실행 결과를 나타내시오

▶ 프로그램
# include < stdio.h >

void main ( void )
{

int c ;

while ( ( c = getc ( stdin ) ) != EOF )
putc ( c , stdout ) ;

}

▶ 실행 결과
The sample C program    Enter
The sample C program
Ctrl z


< fgets ( ) , fputs ( ) >

1. fgets ( ) 함수 ( file get string function )

fgets ( ) 함수의 형식은 다음과 같다.

형 식
char *fgets ( char *str , int n , FILE *fp ) ;

fgets ( ) 함수는 파일 포인터 fp로 지정된 파일로부터 하나의 레코드 ( ' \n ' 까지 ) 또는
n-1 개 이내의 문자를 문자열 포인터 str이 가리키는 장소로 읽어들인 후 '\0'를 추가시
킨다. 하나의 레코드를 읽어들일 경우에 gets ( ) 함수는 ' \n '을 ' \0 '으로 바꾸어 주었으
나 , fgets ( ) 함수는 ' \n ' 까지 기억시키고 그 뒤에 '\0' 을 추가한다.

fgets ( ) 함수는 gets ( ) 함수와 같이 파일의 끝 ( EOF )인 경우 NULL을 되돌린다.


2. fputs ( ) 함수 ( file put string function )

fputs ( ) 함수의 형식은 다음과 같다 .

형 식
char *fputs ( char *str , FILE *fp ) ;

fputs ( ) 함수는 문자열 포인터 str이 가리키는 곳에 기억되어 있는 문자열을 파일 포
인터 fp로 지정한 파일에 출력한다. 이 때 puts ( ) 함수는 ' \n '을 자동으로 추가하였으나 ,
fputs ( ) 함수는 ' \n '을 추가하지 않는다 .

어떤 파일의 내용을 다른 파일로 복사하는 프로그램을 fgets ( ) 함수와 fputs ( ) 함수를 이용 하여 작성하시오 ( copyfile . c )

▶ 프로그램
# include < stdio.h >
# include < stdlib.h >

void main ( int argc , char *argv[ ] )
{

char str[ 81 ] ;

FILE *fp1 , *fp2 ;

if ( argc != 3 )
{

printf ( " Invalid argument \n " ) ;
printf ( " Usage : copyfile file1 file2 \n " ) ;
exit ( -1 ) ;

}

if ( ( fp1 = fopen ( argv[ 1 ] , "r" ) ) == NULL )
{

printf ( " %s not found \n " , argv[ 1 ] ) ;
exit ( -1 ) ;

}

fp2 = fopen ( argv[ 2 ] , "w" ) ;
while ( fgets ( str , 81 , fp1 ) != NULL )
fputs ( str , fp2 ) ;

fclose ( fp1 ) ;
fclose ( fp2 ) ;

}

[ source . dat 의 내용 ]
This is a sample text file .

▶ 실행 결과
c > copyfile  source . dat  target . dat
c > type  target . dat
This is a sample text file .


< fscanf ( ) , fprintf ( ) >

1. fscanf ( ) 함수 ( file scan function )

fscanf ( ) 함수는 파일 포인터로 지정된 파일로부터 데이터를 읽어들이는 것 이외에
는 scanf ( ) 함수와 동일하다.

fscanf ( ) 함수의 형식은 다음과 같다 .

형 식

int fscanf ( FILE *fp , char *format[ , arg , ...... ] ) ;


여기서 fp는 파일에 대한 포인터이고 , format은 입력 양식을 나타내며 , arg는 각종
입력 변수들에 대한 포인터를 나타낸다 . fprintf ( ) 와 printf ( ) , fscanf ( ) 와 scanf ( ) 의
관계는 다음과 같다 .

fprintf ( stdout , format , arg ) <--> printf ( format , arg ) ;
fscanf ( stdin , format , arg ) <--> scanf ( format , arg ) ;

2. fprintf ( ) 함수 ( file print function )

fprintf ( ) 함수는 출력 결과를 파일 포인터로 지정한 파일에 출력하는 것 이외에는
printf ( ) 함수와 동일하다 .

fprintf ( ) 함수의 형식은 다음과 같다 .

형 식

int fprintf ( FILE *fp , char *format[ , arg , ..... ] ) ;


여기서 , fp는 파일에 대한 포인터이고 , format은 출력 양식을 나타내며 , arg는 각종
출력 변수들에 대한 포인터를 나타낸다 .

입력 데이터 파일 ( score . dat )로부터 학생의 성명 , 중간고사 성적 , 기말고사 성적 , 리포트 성적 , 출석 성적을 입력받아 총점을 계산한 후 , 출력 파일 ( report . out )에 출력하는 프로그램 ( score . c )을 작성하시오 ( 단 fscanf ( ) 함수와 fprintf ( ) 함수를 이용 )

▶ 프로그램
# include < stdio.h >
# include < stdlib.h >

void main ( int argc , char *argv[ ] )
{

FILE *fp1 , *fp2 ;
char name[ 10 ] ;
int jun , gimal , rep , chul , total ;

if ( argc != 3 )
{

printf ( " Invalid argument \n " ) ;
exit ( -1 ) ;

}

if ( ( fp1 = fopen ( argv[ 1 ] , "r" ) ) == NULL )
{

printf ( " %s not found \n " , argv[ 1 ] ) ;
exit ( -1 ) ;

}

fp2 = fopen ( argv[ 2 ] , "a" ) ;
fprintf ( fp2 , " \t\t 성 적 일 람 표 \n " ) ;
fprintf ( fp2 ,"================================ \n " ) ;
fprintf ( fp2 , "성명     중간고사    기말고사   리포트   출석   총점 \n" ) ;
fprintf ( fp2 ,"================================ \n " ) ;

while ( ( fscanf ( fp1 , " %s %d %d %d %d " , name , &jun , &gimal , &rep , &chul ) ) != EOF )
{

total = jun + gimal + rep + chul ;
fprintf ( fp2 , " %-8s %9d %9d %9d %9d %9d \n " , name , jun , gimal , rep ,
chul , total ) ;

}

fclose ( fp1 ) ;
fclose ( fp2 ) ;

}

[ score . dat 파일의 내용 ]
강감찬 70 80 10 20
손성일 65 70 09 18
윤영지 85 78 08 19
이순신 69 73 10 15

▶ 실행 결과
c > score  score . dat  report . out
c > type   report . out

성 적 일 람 표

===========================================
성명 중간고사 기말고사 리포트 출석 총점
===========================================
강감찬 70 80 10 20 180
손성일 65 70 09 18 162
윤영지 85 78 08 19 190
이순신 69 73 10 15 168

 


< fread ( ) , fwrite ( ) >

C 언어에서 취급하는 파일에는 텍스트 파일 ( text file )과 이진 파일 ( binary file )이
있다 . 지금까지 취급해 온 파일들은 텍스트 파일로서 인쇄가 가능한 문자들로 구성된
파일을 의미한다. 텍스트 파일의 레코드는 ' \n '으로 구분된다. 그러므로 입력할 때에는
' \n '까지 1개의 레코드로 읽어들이며 , 출력할 때에는 ' \n '까지 1개의 레코드로 출력된
다 . 이진 파일은 인쇄가 불가능한 데이터들로 구성된 파일로서 , 텍스트 파일과는 달리
레코드의 개념이 없으며 , 파일의 처음부터 끝까지 데이터로 연결되어 있다고 볼 수
있다 .

fopen ( ) 함수에서 파일을 열기 ( open ) 할 때에는 파일 모드에 [ 표 13-4 ]에 나타낸 것
과 같은 문자를 추가하여 사용할 수 있다 .

[ 표 13-4 ] fopen ( ) 함수에서 텍스트 파일과 이진 파일의 모드 구분

문 자 의 미
t 텍스트 모드 ( text mode )
b 이진 모그 ( binary mode )

따라서 , fopen ( ) 함수의 파일 모드에 "rt" , "rb" 등과 같이 사용하여 파일을 텍스트
모드 또는 이진 모드로 지정할 수 있다 . 만일 t나 b를 사용하지 않으면 텍스트 모드로
간주한다.


1. fread ( ) 함수 ( file read function )

fread ( ) 함수는 주로 이진 파일의 입력에 많이 사용되며 , 사용 형식은 다음과 같다 .

형 식

int fread ( char *ptr , int size , int items , FILE *fp ) ;

fread ( ) 함수는 파일 포인터 fp로 지정된 파일로부터 크기가 size 바이트인 데이터
블록을 items의 개수만큼 읽어들여 ptr이 가리키는 기억 장소에 기억시킨다 . 이때 기억
장소는 ( size *items ) 바이트만큼 확보되어 있어야 한다 . 즉 ( 데이터의 크기 * 읽어들
일 레코드의 수 )만큼 확보해야 한다 .

fread ( ) 함수는 정상적으로 읽어들인 블록의 수 ( items )를 함수값으로 되돌린다 . 그
러나 EOF 직전까지 items의 개수만큼 읽어들이지 못하였을 경우에는 실제 읽어들인
블록 수를 되돌리며 , EOF나 오류인 경우 0( zero )을 되돌린다 .


2. fwrite ( ) 함수 ( file write function )

fwrite ( ) 함수는 지정된 파일에 블록( 레코드 ) 단위로 쓰기를 하는 함수이다 . 주로
이진 파일의 출력에 사용하며 , 형식은 다음과 같다 .

형 식
int fwrite ( char *buffer , int size , int items , FILE *fp ) ;

fwrite ( ) 함수는 buffer가 가리키는 기억 장소로부터 크기가 size 바이트인 데이터
블록 items개를 파일 포인터 fp로 지정된 파일에 쓰기 ( write )한다 . 정상적으로 실행된
경우에는 출력된 블록의 수 ( items의 수 )를 함수값으로 되돌리지만 , 오류가 발생할 경
우에는 0( zero )을 되돌린다 .

학생들의 성적이 다음과 같은 입력 레코드 형식으로 파일 sample . dat에 기억되어 있다.
이 파일을 읽어들여 출력 레코드 형식으로 파일 temp . out에 출력하는 프로그램을 작성
하시오 ( sungjuk . c )




▶ 프로그램
# include < stdio.h >
# include < stdlib.h >

void main ( int argc , char * argv[ ] )
{

char in_buffer[ 30 ] ;
static char out_buffer[ 38 ] ;
FILE *fp1 , *fp2 ;
void assignment ( char * , char * , int ) ;

if ( argc != 3 )
{

printf ( " Invalid argument \n " ) ;
exit ( -1 ) ;

}

if ( ( fp1 = fopen ( argv[ 1 ] , "r" ) ) == NULL )
{

printf ( " %s not found \n " , argv[ 1 ] ) ;
exit ( -1 ) ;

}

fp2 = fopen ( argv[ 2 ] , "w" ) ;
out_buffer[ 37 ] = ' \n ' ;

while ( fread ( in_buffer , sizeof ( in_buffer ) , 1 , fp1 ) != 0 )
{

assignment ( in_buffer , out_buffer , 5 ) ;
assignment ( in_buffer+5 , out_buffer+7 , 15 ) ;
assignment ( in_buffer+20 , out_buffer+24 , 3 ) ;
assignment ( in_buffer+23 , out_buffer+29 , 3 ) ;
assignment ( in_buffer+26 , out_buffer+34 , 3 ) ;
fwrite ( out_buffer , 38 , 1 , fp2 ) ;

}

fclose ( fp1 ) ;
fclose ( fp2 ) ;

}
void assignment ( char *ptr1 , char *ptr2 , int n )
{

int i ;

for ( i=0 ; i<n ; i++ )
ptr2[ i ] = ptr1[ i ] ;

}

[ 입력 데이터 파일 ] sample . dat

20001 lee sun shin 80 75 100
20002 kim hong gil 100 82 81
20003 choi chun ju 80 100 80
20004 park na lee 85 83 86

▶ 실행 결과
c > sungjuk   sample . dat  temp . out
c > type  temp . out
20001 lee sun shin 80 75 100
20002 kim hong gil 100 82 81
20003 choi chun ju 80 100 80
20004 park na lee 85 83 86


< fseek ( ) >

fseek ( ) 함수는 파일 포인터로 지정된 파일 내에서 다음에 읽기 ( read ) 또는 쓰기
( write ) 할 위치로 읽기/쓰기 위치 포인터를 이동시켜 주는 함수이다 .

fseek ( ) 함수의 형식은 다음과 같다 .

형 식

int fseek ( FILE *fp , long int offset , int mode ) ;


여기서 mode는 기준 주소를 나타내며 그 의미는 [ 표 13-5 ]와 같다 . offset은 long
int 형으로 양수나 음수의 값을 가질 수 있다 . 따라서 fseek ( ) 함수는 파일 포인터 fp가
가리키는 파일의 현재 위치를 mode로 지정한 기준 위치에서 offset 바이트만큼 떨어진
위치로 읽기/쓰기 위치 포인터를 이동시킨다. offset의 값이 양수인 경우에는 순방향
( forward )으로 , 음수인 경우에는 역방향 ( backward )으로 위치가 이동한다.

[ 표 13-5 ] mode
mode 의 미

0

파일의 시작

1

현재의 위치

2

파일의 끝



[ 그림 13-2 ]는 mode와 offset의 관계를 나타낸 것이다.

[ 그림 13-2 ] mode와 offset의 관계

다음 프로그램의 실행 결과를 나타내시오 ( address . c )

▶ 프로그램
# include < stdio.h >
# include < stdlib.h >
# define REC_LEN 48

void main ( int argc , char *argv[ ] )
{

FILE *fp ;
char name[ 10 ] ;
char juso[ 30 ] ;
char tel[ 10 ] ;
int n ;

if ( argc != 2 )
{

printf ( " Invalid argument \n " ) ;
exit ( -1 ) ;

}

if ( ( fp = fopen ( argv[ 1 ] , "r" ) ) == NULL )
{

printf ( " %s not found \n " , argv[ 1 ] ) ;
exit ( -1 ) ;

}

while ( fputs ( "Record Number : " , stdout ) , scanf ( " %d " , &n ) != EOF )
{

fseek ( fp , n*REC_LEN , 0 ) ;
fgets ( name , 10 , fp ) ;
fgets ( juso , 30 , fp ) ;
fgets ( tel , 10 , fp ) ;
printf ( " %s %s %s \n " , name , juso , tel ) ;

}

fclose ( fp ) ;

}

[ 입력 데이터 파일 ] address . dat

김남석 부산시 동래구 낙민동 100번지 55-1234
이나리 서울시 도봉구 산내동 80번지 765-3214
민들레 경남 마산시 대원동 201번지 231-1234

▶ 실행 결과
c > address  address . dat
Record Number : 0   Enter
김남석 부산시 동래구 낙민동 100번지 55-1234
Record Number : 1   Enter
이나리 서울시 도봉구 산내동 80번지 765-3214
Record Number : 2   Enter
민들레 경남 마산시 대원동 201번지 231-1234
Record Number :   Ctrl z

 


< feof ( ) >

feof ( ) 함수는 파일의 끝인지 아닌지를 판별해 주는 함수이다. feof ( ) 함수의 형식은
다음과 같다 .

형 식

int feof ( FILE *fp ) ;


getc ( ) 함수나 fgets ( ) 함수 등은 파일의 끝 ( end of file ) 에러가 발생했을 때 함수
값으로 EOF ( -1 )을 되돌려 준다. -1이 반환되었을 떄 feof ( ) 함수를 이용하여 파일의
끝인지 아닌지를 판단할 수 있다. feof ( ) 함수는 파일의 끝이 아닌 경우에는 함수값으
로 0( zero )을 되돌려 주고, 파일의 끝인 경우에는 0이 아닌 정수값을 되돌려 준다.

다음 프로그램의 실행 결과를 나타내시오

▶ 프로그램
# include < stdio.h >

void main ( void )
{

FILE *fp ;
fp = fopen ( " a : \test . dat " , "r" ) ;

while ( ! feof ( fp ) )
putchar ( getc ( fp ) ) ;

}

▶ 실행 결과
This is the sample file 1
This is the sample file 2
This is the sample file 3


이것은 [ 예제 13 . 2 ]에서 만들어진 test . dat라는 파일을 feof ( ) 함수를 사용하여 이
파일 끝까지 내용을 읽어서 화면에 표시한는 프로그램이다.


< ftell ( ) >

ftell ( ) 함수는 파일 포인터가 가리키는 파일의 현재 위치를 얻는 함수이다. ftell ( )
함수의 형식은 다음과 같다.

형 식

long ftell ( FILE *fp ) ;



다음 프로그램의 실행 결과를 나타내시오

▶ 프로그램
# include < stdio.h >

FILE *stream ;

void main ( void )
{

long position ;
char list[ 100 ] ;

if ( ( stream = fopen ( " Ex13-9 . c " , "r" ) ) != NULL )
{

// 100byte만큼 데이터 읽기
fread ( list , sizeof ( char ) , 100 , stream ) ;

// 데이터가 읽혀진 후의 포인터 얻기
position = ftell ( stream ) ;
printf ( " Position after trying to read 100 bytes : %ld \n " , position ) ;

fclose ( stream ) ;

}

}

▶ 실행 결과
Position after trying to read 100 bytes : 100


< rewind ( ) >

rewind ( ) 함수는 파일 포인터를 파일의 시작 위치로 이동시키는 함수이다. rewind ( )
함수의 형식은 다음과 같다.

형 식

void rewind ( FILE *fp ) ;


다음 프로그램의 실행 결과를 나타내시오

▶ 프로그램
# include < stdio.h >

void main ( void )
{

FILE *fp ;
int data1 , data2 ;

data1 = 1 ;
data2 = -37 ;

if ( ( fp = fopen ( " rewind . out " , "w+" ) ) != NULL )
{

fprintf ( fp , %d %d , data1 , data2 ) ;
printf ( " The values written are : %d and %d \n " , data1 , data2 ) ;

// fp가 가리키는 파일의 시작 위치로 이동

rewind ( fp ) ;

fscanf ( fp , %d %d , &data1 , &data2 ) ;
printf ( " The values read are : %d and %d \n " , data1 , data2 ) ;

fclose ( fp ) ;

}

}

▶ 실행 결과
The values written are : 1 and -37
The values read are : 1 and -37


★ 저수준 파일 입출력 함수 ★

저수준 파일 입출력 함수는 하드웨어를 관리하는 커널( kernel )이라는 프로그램의 일
부이다. < stdio.h > 파일에 선언된 파일 구조 ( file structure )를 이용한 지금까지의 함수
들과 유사한 작업을 하지만 , 버퍼의 할당 , 읽혀지는 바이트 수의 지정 등을 일일이 프
로그래머가 기술해 주어야만 한다.

여기에는 read ( ) , write ( ) , open ( ) , create ( ) , unlink ( ) 등의 함수가 있다. 이러한
함수들을 호출하여 사용하는 것을 시스템 호출 ( system calling )이라 한다. 위에서 말
한 저수준 함수란 수준이 낮다는 말이 아니라 기계 수준에 가까운 함수라는 것을 의
미한다.

이러한 함수들을 사용하는 경우에 수행 속도는 빠르지만 버퍼의 할당, 읽혀지는 바
이트 수 지정 등을 프로그래머가 직접 작성해야 한다. 저수준 함수들은 라이브러리 함
수들처럼 링커( linker )에 의해 연결되는 것이 아니라 프로그램 수행 중에 커널 인터럽
트( kernel interrupt )에 의해 수행된다.

[ 표 13-6 ]은 헤더 파일 < io.h >에 정의되어 있는 저수준 파일 입출력 함수를 나타낸
것이다.

[ 표 13-6 ] 저수준 파일 입출력 함수

함 수 의 미
open ( ) 파일 열기
close ( ) 파일 닫기
create ( ) 파일 생성
read ( ) 파일로부터 데이터 읽기
write ( ) 파일에 데이터 출력
lseek ( ) 주어진 위치로 파일 포인터 이동
unlink ( ) 파일 삭제


< open ( ) >

파일을 열기하는 함수로 일반 형식은 다음과 같다.

형 식
# include < fcntl.h >
# include < io.h >
int open ( char *filename , int mode , [ int access ] ) ;

여기서 , filename은 액세스하려는 파일의 이름을 뜻하며 , mode는 파일 접근 허가를
위한 파일 열기 모드로서 [ 표 13-5 ]에 나타나 있는 것 중에 하나를 선택하면 된다.

[ 표 13-5 ] mode
mode 의 미
O_RDONLY 읽기 전용으로 파일을 연다.
O_WRONLY 쓰기 전용으로 파일을 연다.
O_RDWR 읽기/쓰기 전용으로 파일을 연다.
O_CREAT 새로운 파일을 생성한 후 파일을 연다.
O_TRUNC 이미 존재하는 파일을 열고 그 파일의 내용을 없앤다.
O_EXCL 이미 파일이 존재하면 새로운 파일을 생성하지 않는다.
O_APPEND 이미 파일이 존재하면 파일의 끝에 추가하기 위해 파일을 연다.
O_BINARY 존재하는 파일을 2진 모드로 연다.
O_TEXT 존재하는 파일을 텍스트 모드로 연다.


예를 들면,

int fd ;
fd = open ( " test . dat " , O_RDONLY ) ;

위의 문장은 test . dat라는 파일을 단지 읽기만 위해 파일을 여는 것이다.

이미 존재하는 test . dat라는 파일을 열어서 그 파일의 끝에 내용을 추가하고자 할 경
우에는 다음과 같이 표현할 수 있다 .

int fd ;
if ( ( fd = open ( " test . dat " , O_APPEND ) ) == -1 )
{

printf ( " Can't open  test . data \n " ) ;
exit ( 0 ) ;

}


< close ( ) >

close ( ) 함수는 open ( ) 함수에 의해 열려진 파일을 다음에 다시 사용하기 위해 닫는
다. 정상적으로 파일이 닫혀지면 0( zero )를, 그렇지 않으면 -1 값을 되돌려 준다.

close ( ) 함수의 일반 형식은 다음과 같다.

형 식

int close ( int fd ) ;



다음 프로그램의 실행 결과를 나타내시오

▶ 프로그램
# include < fcntl.h >
# include < sys\types.h >
# include < sys\stat.h >
# include < io.h >
# include < stdio.h >

void main ( void )
{

int fh1 , fh2 ;

fh1 = open ( " test . dat " , O_RDONLY ) ;
if ( fh1 == -1 )

perror ( " open failed on input file " ) ;

else
{

printf ( " open succeeded on input file \n " ) ;
close ( fh1 ) ;

}

fh2 = open ( " result . out " , O_WRONLY | O_CREAT , S_IREAD | S_IWRITE ) ;

if ( fh2 == -1 )

perror ( " Open failed on output file " ) ;

else
{

printf ( " Open succeeded on output file \n " ) ;
close ( fh2 ) ;

}

}

▶ 실행 결과
Open succeeded on input file
Open succeeded on output file

c > type  result . out
line 1
line 2
line 3
line 4
line 5


위 결과 새로운 파일 result . out 파일이 폴더에 존재함을 확인할 수 있다.


< creat ( ) >

creat ( ) 함수는 새로운 파일을 만든다. 이미 파일이 존재할 경우에 이 파일에 데이터
를 쓰기 위해 쓰기 모드와 함께 지정하면 원래 파일의 속성은 그대로 두고 파일의 내
용만 삭제된다. 읽기 모드와 함께 사용하면 에러가 발생한다. creat ( ) 함수는 선행처리
기 부분에 # include < io.h >를 선언해야 한다.

creat ( ) 함수의 일반 형식은 다음과 같다.

형 식
int creat ( char *filename , int access ) ;

예를 들면 ,

int fd ;
fd = creat ( " test . dat " , S_IREAD | S_IWRITE ) ;

는 test . dat라는 파일을 새로 만들어서 읽기/쓰기가 가능하도록 허가하는 것을 의미
한다.

다음 프로그램의 실행 결과를 나타내시오

▶ 프로그램
# include < sys\types.h >
# include < sys\stat.h >
# include < io.h >
# include < stdio.h >
# include < stdlib.h >

void main ( void )
{

int fh ;
fh = creat ( " data " , S_IREAD | S_IWRITE ) ;

if ( fh == -1 )

perror ( " Couldn't create data file " ) ;

else
{

printf ( " Created data file \n " ) ;
close ( fh ) ;

}

}

▶ 실행 결과
Created data file


< read ( ) >

자료를 읽어들이는 함수로 일반 형식은 다음과 같다.

형 식

int i ;
i = read ( fd , buf , n ) ;


지정된 파일 fd로부터 n 바이트를 읽어 buf로 지정된 위치에 기억시킨다. 이때 i에는
실제로 읽혀진 바이트 수가 반환된다. EOF일 경우에는 0이 에러가 발생하면 -1이
반환된다.

다음 프로그램의 실행 결과를 나타내시오

▶ 프로그램
# include < fcntl.h > // O_RDWR 정의
# include < io.h >
# include < stdlib.h >
# include < stdio.h >

char buffer[ 60000 ] ;

void main ( void )
{

int fh ;
unsigned int nbytes = 60000 , bytesread ;

// 데이터 파일 열기
if ( ( fh = open ( " test . dat " , O_RDONLY ) ) == -1 )
{

perror ( " open failed on input file " ) ;
exit ( 1 ) ;

}

// 데이터 읽기
if ( ( bytesread = read ( fh , buffer , nbytes ) ) <= 0 )

perror ( " Problem reading file " ) ;

else
{

printf ( " Read %u bytes from file \n " ,bytesread ) ;
printf ( " 파일 내용 : \n %s \n , buffer ) ;

}

close ( fh ) ;

}

▶ 실행 결과
Read 34 bytes from file
파일 내용 :
line 1
line 2
line 3
line 4
line 5


< write ( ) >

자료를 파일에 출력하는 함수로 일반 형식은 다음과 같다.

형 식

int i ;
i = write ( fd , buf , n ) ;


buf로 지정된 기억 장소의 n바이트를 fd로 지정된 파일에 써 넣는다. i 에는 실제로
써 넣은 바이트 수가 기억된다. 에러가 발생되면 -1 값이 반환된다.

다음 프로그램의 실행 결과를 나타내시오

▶ 프로그램
# include < io.h >
# include < stdio.h >
# include < stdlib.h >
# include < fcntl.h >
# include < sys\types.h >
# include < sys\stat.h >

char buffer[ ] = " This is a test of 'write' function " ;

void main ( void )
{

int fh ;
unsigned byteswritten ;

if ( ( fh = open ( " write.out " , O_RDWR | O_CREAT , S_IREAD | S_IWRITE ) ) !=-1 )
{

if ( ( byteswritten = write ( fh , buffer , sizeof ( buffer ) ) ) == -1 )

perror ( " Write failed " ) ;

else

printf ( " Wrote %u bytes to file \n " , byteswritten ) ;

close ( fh ) ;

}

}

▶ 실행 결과
Wrote 35 bytes to file


< unlink ( ) >

파일을 파일 시스템 ( file system )으로부터 삭제시키는 함수이다. 일반 형식은 다음과
같다.

형 식
unlink ( fd ) ;


다음 프로그램의 실행 결과를 나타내시오

▶ 프로그램
# include < stdio.h >

void main ( void )
{

if ( unlink ( " Ex13-13 . dsw " ) == -1 )

perror ( " Could not delete ' Ex13-13 . dsw ' " ) ;

else

printf ( " Delete ' Ex13-13 . dsw ' \n " ) ;

}

▶ 실행 결과
Deleted ' Ex13-13 . dsw '


< lseek ( ) >

fseek ( ) 함수와 동일한 기능을 수행하는 함수이다. 파일의 읽기/쓰기를 위해 현재
의 파일 포인터를 읽기/쓰기를 원하는 위치로 이동한다. 이 함수의 일반 형식은 다음과
같다.

형 식

long lseek ( int handle , long offset , int orgin ) ;


여기서, handle은 파일 핸들러이다. offset은 이동할 바이트 수로 음수나 양수를 사
용할 수 있다. orgin은 파일 포인터의 위치를 나타내는 모드이다.

lseek ( ) 함수는 handle과 연결된 파일 포인터를 orgin으로 지정하는 모드 ( mode )로
부터 시작하여 offset 바이트 수만큼 이동한다. 이때 모드는 파일 상의 위치를 가리키
는 것으로 < io.h > 안에 정의되어 있는 3개의 기호 상수를 사용하는 것이 좋다. 모드 기
호 상수들은 다음과 같다.

모 드 숫 자 파일 위치
SEEK_SET 0 파일의 시작 위치에서부터
SEEK_CUR 1 현재 파일 포인터의 위치에서부터
SEEK_END 2 파일의 끝에서부터

lseek ( ) 함수는 파일의 특정 위치로부터 offset이 지정한 바이트 수만큼 파일 포인터
를 이동하고, 새로운 위치의 오프셋을 반환한다. 만약 실패하면 -1L을 리턴하고, 다음
중 하나로 에러를 설정한다.

에러 ( error )의 종류 의 미
EBADF Bad number 잘못된 파일 번호
EINVAL Invalid argument 부적절한 변수

터미널이나 프린터와 같이 탐색이 불가능한 디바이스에 대해서는 반환 값이 정의되
어 있지 않다.

다음 프로그램의 실행 결과를 나타내시오

▶ 프로그램
# include < io.h >
# include < fcntl.h >
# include < stdlib.h >
# include < stdio.h >

void main ( void )
{

int fh ;
long pos ;
char buffer[ 10 ] ;

fh = open ( " Ex13-14.c " , O_RDONLY ) ;

// 파일의 시작 위치 검색
pos = lseek ( fh , 0L , SEEK_SET ) ;

if ( pos == -1L )

perror ( " lseek to beginning failed " ) ;

else

printf ( " Position for beginning of file seek = %ld \n " , pos ) ;

// 파일로부터 데이터 읽기
read ( fh , buffer , 10 ) ;

// 현재 위치 찾기
pos = lseek ( fh , 0L , SEEK_CUR ) ;

if ( pos == -1L )

perror ( " lseek to current position failed " ) ;

else

printf ( " Position for current position seek = %ld \n " , pos ) ;

// 파일 끝 설정
pos = lseek ( fh , 0L , SEEK_END ) ;

if ( pos == -1L )

perror ( " lseek to end failed " ) ;

else

printf ( " Position for end of file seek = %ld \n " , pos ) ;

close ( fh ) ;

}

▶ 실행 결과
Position for beginning of file seek = 0
Position for current position seek = 10
Position for end of file seek = 193


★ Appendix 부록 ★

헤더 파일 내 용
< conio.h > 입출력 포트 ( port )와 콘솔 ( console )에 관련된 모든 함수를 선언하고 있다.
< ctype.h > 문자 분류에 사용되는 전역 변수를 선언하고, 이에 대한 상수와 매크로를 정의한다. 예를 들면 islower ( ) , toascii ( ) , tolower ( ) 와 같은 매크로와 _upper , _lower와 같은 상수를 정의하고 , _ctype과 같은 전역 변수를 선언한다.
< direct.h > chdir ( ) , getcwd ( ) , mkdir ( )와 , rmdir ( )와 같이 디렉토리를 제어하는 함수를 포함하고 있다.
< dos.h > int86 , int86x , intdos와 같이 MS-DOS 인터페이스 함수에 대한 매크로 정의, 함수 선언, 형 정의를 포함하고 있다.
< errno.h > errno 변수의 값을 정하기 위하여 시스템 수준의 호출에서 사용되는 값을 정의한다.
< fcntl.h > 파일이 텍스트 모드 또는 이진 모드로 해석되는지를 제어하고 , 파일이 열리는 연산자의 형을 서술하기 위하여 호출되는 open ( )과 fopen ( )에서 사용되는 플래그 ( flag )를 정의한다.
< io.h > eof ( ) , open ( ) , tell ( ) read ( ) , lseek ( )와 같이 저수준 입출력 함수와 파일 처리에 필요한 함수를 선언하고 있다.
< malloc.h > calloc ( ) , malloc ( ) , realloc ( )과 같이 동적으로 메모리를 할당하는 함수를 선언하고 있다.
< math.h > sqrt ( ) , sin ( ) , log10 ( ) , pow ( )와 같은 모든 수학 함수를 선언하고 있다.
< memory.h > memcpy ( ) , memcmp ( ) , memset ( )와 같은 버퍼 변경 루틴에 대한 함수를 선언하고 있다.
< process.h > abort ( ) , exit ( ) , execle ( ) , system ( )과 같은 모든 프로세스 제어 함수를 선언하고 있다.
< search.h > bsearch ( ) , qsort ( )와 같은 함수를 선언하고 있다.
< signal.h > signal ( )과 같은 신호에 대한 함수를 정의하고 있다.
< stdio.h > fclose ( ) , fopen ( ) , gets ( ) , fread ( ) , scanf ( ) , printf ( ) , fprintf ( ) , fscanf ( )와 같이 스트림 입출력에 대한 함수 선언 및 매크로와 FILE과 같은 자료형 , EOF , NULL , BUFSIZ와 같은 상수를 정의하고 있다.
< stdlib.h > abs ( ) , atoi ( ) , itoa ( ) , rand ( ) , toupper ( ) , getenv ( )와 같은 함수 선언과 errno와 같은 전역 변수를 선언하고 있다.
< string.h > strcat ( ) , strcpy ( ) , strcmp ( ) , strncmp ( )와 같은 문자열 처리 함수를 포함하고 있다.


10진수 ASCII 문자 10진수 ASCII 문자 10진수 ASCII 문자 10진수 ASCII문자
000 NUL 032 ( SPACE ) 064 @ 096
001 SOH 033 ! 065 A 097 a
002 STX 034 " 066 B 098 b
003 ETX 035 # 067 C 099 c
004 EOT 036 $ 068 D 100 d
005 ENQ 037 % 069 E 101 e
006 ACK 038 & 070 F 102 f
007 BEL 039 ' 071 G 103 g
008 BS 040 ( 072 H 104 h
009 HT 041 ) 073 I 105 i
010 LF 042 * 074 J 106 j
011 VT 043 + 075 K 107 k
012 FF 044 , 076 L 108 l
013 CR 045 - 077 M 109 m
014 SO 046 . 078 N 110 n
015 SI 047 079 O 111 o
016 DLE 048 0 080 P 112 p
017 DC1 049 1 081 Q 113 q
018 DC2 050 2 082 R 114 r
019 DC3 051 3 083 S 115 s
020 DC4 052 4 084 T 116 t
021 NAK 053 5 085 U 117 u
022 SYN 054 6 086 V 118 v
023 ETB 055 7 087 W 119 w
024 CAN 056 8 088 X 120 x
025 EM 057 9 089 Y 121 y
026 SUB 058 : 090 Z 122 z
027 ESC 059 ; 091 [ 123 {
028 FS 060 < 092 124 |
029 GS 061 = 093 ] 125 }
030 RS 062 > 094 126 ~
031 US 063 ? 095 _ 127 DEL