7.7 행 입출력(Line Input and Output)
표준 라이브러리는 이전의 장들에서 사용한 getline 함수와 유사한 fgets 입력함수를 가지고 있다.
char *fgets(char *line,int maxline,FILE *fp)
fgets는 다음 입력행('\n'을 포함한)을 파일 fp로부터 문자열(즉 문자 배열)인 line에 읽어들이는데,최대 maxline-1 문자를 읽을 수 있다. 입력 완료된 라인은 '\0'에 의해 종료된다. 보통 fgets는 line을 리턴하는데,파일의 끝이너가 에러를 만났을 시에는 NULL을 리턴한다(getline 함수는 행의 길이를 리턴시키는데 이것이 더 쓸모 있는 값이다.0은 파일의 끝을 의미하게 된다.)
출력함수 fputs는 '\0'을 포함하지 않는 문자열을 파일에 출력시킨다
int fputs(char *line, FILE *fp)
에러가 발생하면 EOF를 리턴하고, 나머지 경우에는 0을 리턴한다
라이브러리 함수 gets와 puts는 fgets나 fputs와 유사하지만 stdin과 stdout에 적용되는 것이 자른 점이다. 혼란스럽게 gets는 마지막의 '\n'을 제거하지만 puts는 그것을 추가한다.
여기에서 fgets나 fputs와 같은 함수가 별로 특별한 점이 없다는 것을 보여주기 위해 프로그램 리스트를 다음에 실었다.
/* fgets: get at most n chars from iop */
char *fgets(char *s, int n, FILE *iop)
{
register int c;
register char *cs;
cs = s;
while (--n > 0 && (c = getc(iop)) != EOF)
if ((*cs++ = c) == '\n')
break;
*cs = '\0';
return (c == EOF && cs == s) ? NULL : s;
}
/* fputs: put string s on file iop */
int fputs(char *s, FILE *iop)
{
int c;
while (c = *s++)
putc(c, iop);
return ferror(iop) ? EOF : 0;
}
특별한 이유는 없지만 ferror과 fputs의 리턴값은 다르게 되어 있다 fgets를 사용해서 getline을 작성하는 것은 어렵지 않다.
/* getline: read a line, return length */
int getline(char *line, int max)
{
if (fgets(line, max, stdin) == NULL)
return 0;
else
return strlen(line);
}
예제 7-6 두 파일을 비교하여 내용이 다른 첫번째 행을 출력하게 하는 프로그램을 작성하라.
예제 7-7 제 5장 패턴찾는 프로그램을 수정하되 입력은 이름이 정해진 파일에서 받아들이거나, 파일 이름이 매개변수로 주어지지 않으면,쵸준 입력으로 받아들이도록 하라. 패턴이 일치하는 행이 발견될 때 파일 이름을 출력하게 할 수 있는가를 알아보라
예제 7-8 여러 개의 파일을 출력시키키는 프로그램을 작성하라. 각 프로그램은 새 페이지에서 시작 해야 하고 프로그램 위에 파일 이름이 출력되고 프로그램마다 1부터 시작하도록 페이지 번호를 붙인다.