perror ( "…") 및 fprintf (stderr, "…")는 언제 사용해야합니까?


105

맨 페이지를 읽고 몇 가지 코드는 정말 사이의 차이를 이해하는 나에게 도움이되지 않았다 - 내가 사용해야 할 때, 더 나은 또는 - perror("...")fprintf(stderr, "...").

답변:


113

호출 perrorerrnoPOSIX 시스템 호출 에 의해 작성된 스레드 로컬 오류 값인 의 해석 된 값을 제공합니다 (즉, 모든 스레드에는에 대한 자체 값이 있음 errno). 예를 들어를 호출 open()하고 오류가 생성 된 경우 (즉,를 반환 한 경우 -1) perror즉시 호출 하여 실제 오류가 무엇인지 확인할 수 있습니다. 그 동안 다른 syscall을 호출하면 in 값 errno이 덮어 쓰여지고, perror이전 syscall에서 오류가 생성 된 경우 문제를 진단하는 데 호출 이 아무 소용이 없습니다.

fprintf(stderr, ...)반면에 사용자 정의 오류 메시지를 인쇄하는 데 사용할 수 있습니다. 로 인쇄하면 stderr오류보고 출력이로 이동해야하는 "일반"출력과 혼합되는 것을 방지 할 수 있습니다 stdout.

를 호출 하면에 대한 인쇄 된 문자열 값이 생성 되고을 통해 다른 사용자 지정 오류 메시지와 결합 할 수 있기 때문에 fprintf(stderr, "%s\n", strerror(errno))와 비슷합니다 .perror(NULL)strerror(errno)errnofprintf


3
오, 알겠습니다. perror 함수는 errno의 값에 따라 다르게 작동합니다. If you use a function that effects errno then it makes sense to use perrorerrno에 영향을주지 않고 단순히 오류 코드를 반환하는 함수를 사용하는 경우 fprintf (stderr, fmt, ...)를 사용해야합니다. 예를 들어 strtol은 문자열이 범위를 벗어나면 LONG_MAX 또는 LONG_MIN을 반환하고 errno를 ERANGE로 설정합니다. 따라서 범위를 벗어 났기 때문에 strtol이 실패하면 공포를 사용합니다.
freeboy1015 2012-08-24

6
하나의 세부 사항 strerror은 스레드로부터 안전 할 필요가 없습니다. 멍청하지만 표준입니다. strerror_l대신 POSIX 2008 시스템에서 드롭 인 교체로 사용할 수 있습니다. strerror_r이전 시스템에서도 사용할 수 있지만 일부 시스템에 부적합 버전이있는 경우에는 정말 심각한 문제가 있습니다.
R .. GitHub의 STOP 돕기 ICE

또한 nitpick으로, 마지막에 perror추가 '\n'하여 형식이 "%s\n", no?
옌스 Gustedt

1
@R .., 하, 나는 이미 가지고 있으며, 내가 아는 한 그들은 나에게 돈을 지불하지 않습니다. 그리고 MS가 C에 대한 지원을 완전히 중단하는 것처럼 보이므로 결국 나는 유일한 사람이 될 것입니다 :) strerror_s실제로 인터페이스만큼 나쁘지 않습니다.
Jens Gustedt

2
지원을 완전히 절단 하시겠습니까? 다시위원회를 속인 것 같습니다. 그들의 _s쓰레기를 표준에 넣는 것은 기본적으로 MS의 게임이었습니다 ( "인터페이스를 채택하면 실제로 우리 제품이 표준을 지원하도록 고려할 것입니다."). 물론 지금은이를 따르지 않고 있습니다. 사실 저는이 인터페이스가 그 자체로 나쁘지 않다는 데 동의합니다. 나쁜 점은 대부분의 표준 라이브러리가 "안전하지 않다"고 표준 라이브러리 _s대신 전체 함수 제품군을 사용해야한다는 선전 (컴파일러 경고의 형태로) 입니다.
R .. GitHub STOP HELPING ICE

40

그들은 다소 다른 일을합니다.

에 해당 perror()하는 메시지를 인쇄하는 데 사용 stderr합니다 errno. 당신이 사용하는 fprintf()인쇄 무엇stderr, 또는 어떤 다른 스트림을. perror()매우 전문화 된 인쇄 기능입니다.

perror(str);

다음과 같다

if (str)
    fprintf(stderr, "%s: %s\n", str, strerror(errno));
else
    fprintf(stderr, "%s\n", strerror(errno));

12

perror(const char *s): 사용자가 제공 한 문자열 뒤에의 현재 값을 설명하는 문자열을 인쇄합니다 errno.

stderr: 자신의 오류 메시지를 (기본값은 터미널)로 파이프하는 데 사용되는 출력 스트림입니다.

관련된:

char *strerror(int errnum): 오류 번호를 제공하면 관련 오류 문자열을 반환합니다.


2

perror ()는 항상 stderr에 기록합니다. fprintf ()와 함께 사용되는 strerr ()은 stderr을 포함하여 모든 출력에 쓸 수 있지만 배타적이지는 않습니다.

fprintf(stdout, "Error: %s", strerror(errno));
fprintf(stderr, "Error: %s", strerror(errno)); // which is equivalent to perror("Error")

또한 perror는 "text : error description"이라는 자체 텍스트 형식을 부과합니다.


-2

Perror 함수는 실행 호출을 수행하는 데 더 많은 시간이 소요됩니다. fprintf 호출은 API에서 커널로 이동하는 동안 사용자 공간에서 커널 공간으로 이동합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.