2013-05-16 3 views
0

표준 에러 : 쉘이 아무것도 stdin를 리디렉션 할 수 있기 때문에,캐치 오류, 내가 표준 입력에서 읽기 비트 C99 코드를 작성했다

// [...] 
fgets(buf, sizeof(buf), stdin); 
// [...] 

을하지만이 경우 오류를 포착해야하는지 궁금하고 일반 stdin보다 덜 강력합니다. 그러나 이는 또한 stdin, stdoutstderr에 대한 모든 액세스에 오류가 있는지 확인해야하며 printf 및 co 다음에 어떤 검사도 거의 볼 수 없다는 것을 의미합니다.

그래서 모든 스트림 액세스에 오류가 있는지 확인하는 것이 좋습니다? 사전에

// [...] 
if (!fgets(buf, sizeof(buf), stdin) && ferror(stdin)) { 
    exit(EXIT_FAILURE); 
} 
// [...] 

감사 :

위의 예는 무엇인가 등이 될 것입니다!

답변

1

개발중인 응용 프로그램의 특성에 따라 다릅니다. 예를 들어, 비정상 종료로 인해 심각한 문제가 발생하는 하드 실시간 시스템을 개발중인 경우 모든 종류의 데이터 스트리밍 오류를 처리하기 위해 예방 조치를 취해야합니다. 이러한 경우 다음 코드를 사용하십시오.

if (!fgets(buf, sizeof(buf), stdin) && ferror(stdin)) { 
    exit(EXIT_FAILURE); 
} 

또는 이와 유사한 구조를 사용하십시오. 그러나 응용 프로그램의 드문 오류가 심각한 결과를 초래하지 않으면 모든 데이터 스트리밍 작업을 확인할 필요가 없습니다.

3

항상 사용할 때마다 fgets()에서 반환 값을 확인해야합니다. 그렇지 않다면 버퍼에 유용한 데이터가 있는지 알 수 없습니다. 마지막 줄을 두 번째로 유지할 수 있습니다. 비슷한 코멘트가 모든 읽기 작업에 적용됩니다. 읽기 작업이 예상 한 것을 반환했는지 확인해야합니다.

처리 코드에서 수행 할 작업을 결정해야합니다. 해당 코드에 feof()ferror()을 정당하게 사용할 수 있습니다. 문제에 대한 올바른 반응은 코드에 따라 다릅니다. EOF를 감지하면 일반적으로 루프를 종료하거나 함수를 종료하는 원인이됩니다 (break 또는 return). 함수가 파일을 열지 않은 경우에만 반환되며, 그렇지 않으면 최소한 파일을 닫아야합니다. stdin에서 오류를 감지하는 경우는 거의 없습니다. 당신은 무엇이 적절한가를 결정해야 할 것입니다.

stderr 또는 stdout에 대한 쓰기 오류는 자주 발생하지 않지만이를 생략하는 것은 틀림없이 엉성한 프로그래밍입니다. 한 가지 문제, 특히 문제가있는 stderr 인 경우 "오류를 신고 하시겠습니까?" 대신 syslog()을 사용해야 할 수도 있지만, 생각해야 할 문제입니다.

+0

감사합니다. 전에 syslog에 대해 들어 본 적이 없습니다. 잘 알고 있습니다. 그러나 EOF에 대해 : 때로는 미리 초기화 된 버퍼가 있고 변경되지 않았는지 신경 쓰지 않아도 괜찮습니다. 반환 값은 항상주의해야합니다. – user1678062

0

다음은 재미있는 연습입니다. 대화식 프로그램을 찾아 터미널에서 입력을 요청할 때까지 실행 한 다음 control-D (EOF)를 누릅니다. 확률은 저자가 feof (stdin)를 체크하지 않고 그의 gets() 호출은 코드가 공백 행으로 해석하는 0 바이트를 반환하는 것을 유지한다는 것입니다. 유효하지 않은 입력과 재 입력으로 처리한다면 무한 루프가됩니다!

관련 문제