맨 페이지를 읽고 몇 가지 코드는 정말 사이의 차이를 이해하는 나에게 도움이되지 않았다 - 내가 사용해야 할 때, 더 나은 또는 - perror("...")
나 fprintf(stderr, "...")
.
맨 페이지를 읽고 몇 가지 코드는 정말 사이의 차이를 이해하는 나에게 도움이되지 않았다 - 내가 사용해야 할 때, 더 나은 또는 - perror("...")
나 fprintf(stderr, "...")
.
답변:
호출 perror
은 errno
POSIX 시스템 호출 에 의해 작성된 스레드 로컬 오류 값인 의 해석 된 값을 제공합니다 (즉, 모든 스레드에는에 대한 자체 값이 있음 errno
). 예를 들어를 호출 open()
하고 오류가 생성 된 경우 (즉,를 반환 한 경우 -1
) perror
즉시 호출 하여 실제 오류가 무엇인지 확인할 수 있습니다. 그 동안 다른 syscall을 호출하면 in 값 errno
이 덮어 쓰여지고, perror
이전 syscall에서 오류가 생성 된 경우 문제를 진단하는 데 호출 이 아무 소용이 없습니다.
fprintf(stderr, ...)
반면에 사용자 정의 오류 메시지를 인쇄하는 데 사용할 수 있습니다. 로 인쇄하면 stderr
오류보고 출력이로 이동해야하는 "일반"출력과 혼합되는 것을 방지 할 수 있습니다 stdout
.
를 호출 하면에 대한 인쇄 된 문자열 값이 생성 되고을 통해 다른 사용자 지정 오류 메시지와 결합 할 수 있기 때문에 fprintf(stderr, "%s\n", strerror(errno))
와 비슷합니다 .perror(NULL)
strerror(errno)
errno
fprintf
strerror
은 스레드로부터 안전 할 필요가 없습니다. 멍청하지만 표준입니다. strerror_l
대신 POSIX 2008 시스템에서 드롭 인 교체로 사용할 수 있습니다. strerror_r
이전 시스템에서도 사용할 수 있지만 일부 시스템에 부적합 버전이있는 경우에는 정말 심각한 문제가 있습니다.
perror
추가 '\n'
하여 형식이 "%s\n"
, no?
strerror_s
실제로 인터페이스만큼 나쁘지 않습니다.
_s
쓰레기를 표준에 넣는 것은 기본적으로 MS의 게임이었습니다 ( "인터페이스를 채택하면 실제로 우리 제품이 표준을 지원하도록 고려할 것입니다."). 물론 지금은이를 따르지 않고 있습니다. 사실 저는이 인터페이스가 그 자체로 나쁘지 않다는 데 동의합니다. 나쁜 점은 대부분의 표준 라이브러리가 "안전하지 않다"고 표준 라이브러리 _s
대신 전체 함수 제품군을 사용해야한다는 선전 (컴파일러 경고의 형태로) 입니다.
그들은 다소 다른 일을합니다.
에 해당 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));
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"이라는 자체 텍스트 형식을 부과합니다.
If you use a function that effects errno then it makes sense to use perror
errno에 영향을주지 않고 단순히 오류 코드를 반환하는 함수를 사용하는 경우 fprintf (stderr, fmt, ...)를 사용해야합니다. 예를 들어 strtol은 문자열이 범위를 벗어나면 LONG_MAX 또는 LONG_MIN을 반환하고 errno를 ERANGE로 설정합니다. 따라서 범위를 벗어 났기 때문에 strtol이 실패하면 공포를 사용합니다.