7.6 에러처리:stderr와 exit(Error Handling - Stderr and Exit)
cat 함수의 에러처리 방법은 그다지 좋은 편이 아니다 만약 파일중 하나가 어떤 이유로 액세스 될 수 없을때 에러메시지가 출력문의 끝에 나타난다. 이런 출력이 화면상에서 나타난다면 별 문제가 없지만 파이프라인을 통해 다른 파일이나 프로그래멩 들어가면 곤란하게 된다.
위의 문제를 해결하기 위해서 stderr로 불리는 또 하나의 stream을 stdin이나 stdout과 같은 방법으로 프로그램에서 지정한다.표준 출력의 방향이 다시 지정되더라도 stderr의 에러문은 화면상에 나타나게된다.
위의 것을 이용하여 cat를 표준 에러 파일에 에러메시지를 나타내도록 해보자.
#include <stdio.h>
/* cat: concatenate files, version 2 */
int main(int argc, char *argv[])
{
FILE *fp;
void filecopy(FILE *, FILE *);
char *prog = argv[0]; /* program name for errors */
if (argc == 1 ) /* no args; copy standard input */
filecopy(stdin, stdout);
else
while (--argc > 0)
if ((fp = fopen(*++argv, "r")) == NULL) {
fprintf(stderr, "%s: can't open %s\n",
prog, *argv);
exit(1);
} else {
filecopy(fp, stdout);
fclose(fp);
}
if (ferror(stdout)) {
fprintf(stderr, "%s: error writing stdout\n", prog);
exit(2);
}
exit(0);
}
이 프로그램은 두가지 방법으로 에러를 알란다. 첫째 fprintf에 의해 만들어진 에러 메시지를 stderr로 보내면 에러 메시지가 사용자의 화면에 나타나게 된다. 프로그램 이름을 argv[0]으로부터 포함 했으므로 이프로그램이 다른것과 함께 사용 되더라도 에러의 근원지는 구별된다.
둘째 표준 라이브러리 함수 exit를 사용하는 방법이다. 그런데 이것이 호출되면 프로그램의 수행이 끝나게 된다. exit의 리턴 값은 다른 프로그램에서도 사용할 수 있으므로 그 프로그램 수행의 성공여부를 검사하는 프로그램을 작성할 수있다. exit가 0값을 리턴하면 모든게 잘되고 있는 것이고0이아닌 값을 리턴하면 대개 비정상적이라는 암시를 나타낸다 exit는 열린(open)파일에 대해 fclose를 호출하여 버퍼를 지우고 파일을 닫는다(close)
main 함수에서는 return expr 이라고 표현 하는 것과 exit(expire)이라고 표현하는 것은 똑같다. 그러나 exit는 다른 함수로부터 호출할 수 있는 유리한 점을 가지고 있다 함는 fp에 에러가 발생한다면 0이 아닌 값을 리턴한다.
int ferror(FILE *fp)
출력 에러는 매우 드물긴 하지만 발생할 여지가 있다(예:디스크가 꽉 차 있을경우).그렇기 때문에 프로그램에서이 점을 잘 검사해야 한다 함수 feof(FILE *)는 ferror의 유사형이다. 이 함수는 파일의 끝을 발견하면 0이 아닌값을 리턴한다.
int feof(FILE *fp)
여기서 예를 든 프로그램에서는 exit의 리턴값에 주의하지 않았지만 고수준의 프로그램에서는 리턴값 상태에 주의를 기해야만 한다.