오류를 처리하는 Hello World


9

다음 기능을 가진 프로그램 또는 기능을 작성하십시오.

  • 프로그램 / 함수는 먼저 문자열 Hello, world!을 표준 출력 스트림 에 쓰려고 시도 합니다. (프로그램 자체의 사소한 행동보다는 I / O에 중점을두기 때문에이 과제에 다른 형식의 출력을 사용할 수 없습니다.) 성공 여부에 따라 :
    • 출력에 성공 Hello, world!하면 추가 동작없이 프로그램 / 기능이 종료됩니다.
    • 오류로 인해 올바른 출력을 생성하지 못한 경우 프로그램 / 기능은 문자열 Error writing "Hello, world!"을 표준 오류 스트림 에 쓰려고 시도 합니다. (이 도전의 목적으로, 오류 처리 자체를 위해 오류 처리가 필요하지 않습니다.)

설명

  • 프로그램 / 기능은 입력없이 실행됩니다 (입력이 작동해야하는 언어로 작성되지 않은 경우 가장 간단한 입력으로 실행 됨).

  • 출력을 생성 할 때 원하는 경우 단일 후행 줄 바꿈을 생성 할 수도 있지만 그렇게하는 것이 필수는 아닙니다.

  • 프로그램이 구현하는 "표준 출력에 오류 쓰기"의 정의는 최소한 다음 경우를 오류로 처리해야합니다.

    • 표준 출력이 존재하지 않습니다 (즉 stdout, 닫힌 파일 핸들이거나 파일 디스크립터 1이 없거나 이러한 경우 사용중인 언어 및 OS로 변환 됨).
    • 여유 공간이없는 디스크의 파일을 참조하는 표준 출력.
    • 연결 종료를 이미 닫은 다른 프로그램에 연결하는 표준 출력.

    최소한 다음과 같은 경우를 성공으로 취급해야합니다 (예 : 오류가 아님).

    • 표준 출력은 터미널에 연결되고 Hello, world!화면에 표시됩니다.
    • 표준 출력은 파일에 연결되어 파일에 Hello, world!기록됩니다.

    위의 규칙과 일치하는 한 출력 오류로 간주되는 세부 정보를 선택할 수 있습니다.

  • 위에 나열된 오류 상황이 발생하면 프로그램 / 기능이 충돌하지 않아야합니다. 사용하는 종료 코드는 사용자에게 달려 있습니다.

  • 프로그램 / 기능은 표준 오류 스트림에서 발생한 오류의 특성을 설명해서는 안됩니다. 위에 지정된 문자열 만 인쇄해야합니다. 표준 오류에 대한 외부 출력 (예 : 컴파일러 경고)은 오류 발생 여부에 관계없이 무조건 생성되는 경우에만 유효합니다.

  • 귀하의 프로그램은 하나의 운영 체제에서만 작동해야합니다 (위에 나열된 오류가 의미가있는 것이어야하지만 대부분의 멀티 태스킹 소비자 운영 체제에서 작동 할 수 있도록 일반적으로 유지하려고 노력했지만 이상한 운영 체제는 잘 작동 할 수 있습니다 이 과제에서 제외됨). 프로그램을 이식 할 수없는 경우 제출 제목에 실행해야하는 가정을 나열하십시오.

  • 이 작업은 모든 언어에서 가능하지 않을 수 있습니다 (모든 언어가 프로그램이 사용자 정의 방식으로 출력 오류를 처리하도록 허용하는 것은 아닙니다). 가능한 언어를 선택해야합니다.

  • 프로그램 / 기능이 작동하는지 확인하십시오! 그들이하는 말을하기 위해 라이브러리 함수의 문서를 신뢰하지 마십시오. 간단한 출력 함수의 오류 처리는 이론적으로 함수가 오류를 처리한다고 주장하더라도 실제로 실제로 깨지는 것으로 판명됩니다.

테스트 사례

bashLinux에서 위의 각 오류 조건을 시뮬레이션하는 방법은 다음과 같습니다 (Linux를 사용할 필요는 없지만이를 테스트하는 가장 쉬운 시스템 일 것입니다).

your_program_here >&-           # nonexistent stdout
your_program_here > /dev/full   # out of disk space
mkfifo test  # note: change "test" to a filename that isn't in use
true < test &
your_program_here > test        # connecting to a program that doesn't want input
rm test      # clean up the FIFO we used earlier

처음 두 테스트 케이스는 결정적입니다. 마지막은 아니다 (경쟁 조건에 의존한다); 테스트 목적으로, 경쟁 조건이 오류를 노출시키는 방식으로 해결 될 수 있도록 프로그램 시작과 실제 출력 사이에 지연을 추가하는 것이 좋습니다.

승리 조건

이것은 도전, 그래서 짧을수록 좋습니다. (거의) 항상 그렇듯이 우리는 프로그램의 길이를 바이트 단위로 측정하고 있습니다.


1
Windows에서 이것을 테스트하는 방법이 있는지 알고 있습니까? 나는 첫 번째 기준을 테스트 할 수 있지만 디스크에 대한이 아닌 부분은 ... 전체 인
스튜이 그리핀

경쟁 조건을 줄이려면 사용할 수 sleep 1 < test; (sleep 2; your_program_here) > test있습니까?
Neil

답변:


6

배쉬 , 71 60 바이트

h=Hello,\ world!
(echo $h)2>&-||echo Error writing \"$h\">&2

온라인으로 사용해보십시오!

작동 원리

Hello, world!변수 h에 저장 한 후 다음을 수행합니다.

먼저 STDOUT (echo $h)2>&-으로 인쇄 Hello, world!를 시도합니다 . 2>&-오류 메시지를 표시하지 않으려면 에코 가 필요합니다 . 쓰기 오류 : 쓰기에 실패한 경우 파일 설명자가 잘못 되었습니다. 입력을받지 않는 명명 된 파이프에 쓰면 신호 13 (SIGPIPE)으로 Bash 프로그램이 종료 (...)되므로 서브 쉘 ( ) 에서 명령을 실행 하므로 서브 쉘 만 종료됩니다.

마지막으로 STDOUT으로 인쇄에 실패하면 서브 쉘은 0이 아닌 상태 코드 (SIGPIPE의 경우 141, 일반 오류의 경우 1)로 종료되므로 echo Error writing \"$h\">&2원하는 메시지를 STDERR에 인쇄합니다.




1

C (gcc) , 87 86 바이트

f(){signal(13,1);write(1-puts("Hello, world!"),"Error writing \"Hello, world!\"",29);}

온라인으로 사용해보십시오!

언 골프

#include <signal.h>
#include <stdio.h>
#include <unistd.h>

void f(void)
{
    signal(SIGPIPE, SIG_IGN); // Works (and is required) on TIO. YMMV
    int fd = (puts("Hello, world!")) < 0 ? 2 : -13;
    write(fd, "Error writing \"Hello, world!\"", 29);
}

반품에 대해 어떻게 알 수 있습니까? 여기에 모든 것이 괜찮을 때> = 0이라고 말합니다.
RosLuP

puts오류가 발생한 경우 쓰여진 바이트 수 또는 -1 을 반환하므로 14 (Hello World plus newline) 또는 -1을 반환합니다 . (이것은 플랫폼에 따라 다를 수 있지만 이것이 glibc와 함께 작동하는 방식입니다.)
Dennis

K & R2는 오류가 발생하면 EOF를 [-1 실질적으로] 반환합니다. 또는 괜찮 으면 음수가 아닌 값
RosLuP

1
PPCG에서 언어는 구현에 의해 정의되며 gcc / glibc는 내가 말한 것처럼 작동합니다.
Dennis

나는 오래된 책을 선호합니다
RosLuP

1

PowerShell, 80 바이트

try{echo($h="Hello, World!") -ea 4}catch{$host.ui|% *rL* "Error writing ""$h"""}

설명 :

try{
    #Attempt to 'echo' (write output) the string, and assign it to $h
    #Make sure the 'error action' is set to '4' to make it a terminating error.
    echo($h="Hello, World!") -ea 4
} catch { 
    #Use the "WriteErrorLine" function in $host.ui to stderr
    $host.ui|% *rL* "Error writing ""$h"""
}

오류가 발생했을 때 실제로 시도하지는 않았지만 확실히 작동해야합니다.


오류 메시지는 STDERR에 작성해야합니다 . 첫 번째 쓰기 시도 중에 오류가 발생하면 STDOUT에 쓸 수 없습니다.
데니스

@Dennis 덕분에 업데이트되어 질문을 완전히 읽지 못했습니다.
colsw

Afaict PowerShell은 치명적인 예외 만 포착하므로 필요할 Write-Host -ErrorAction Stop수도 있습니다. 또한 throw인쇄 해야하는 줄을 제외하고 추가 디버깅 정보를 생성합니다 .HW 문자열 주위에 소문자 W 와 큰 따옴표가 있어야합니다.
Dennis

@Dennis 추가 디버그 정보가 저를 짓 밟았습니다.
colsw

1

자바 스크립트, 79 76 바이트

try{(l=console).log(a="Hello, world!")}catch(e){l.error('Error writing '+a)}

출력해야하는 문자열 'Hello, world!'은 사용하는 것보다 1 바이트 더 깁니다. 또한 a호출 내부에 할당하는 console.log것이 짧아지고 (1B) l.log(a)다른 바이트를 저장 한 후 세미콜론을 제거 한다고 가정 합니다.
Luke

@Luke 감사합니다, 그것은 큰 실수였습니다!
Matthew Roh

1
try{(l=console).log(a="Hello, world!")}catch(e){l.error('Error writing '+a)}76 바이트 먼저에 console할당 된 l다음 "Hello, world!'에 할당 된 a다음 실행됩니다.
Luke

0

펄 5, 51 바이트

필요합니다 ( -M5.01무료)

say$h="Hello, world!"or die"Error writing \"$h\"$/"

프로그램을 그대로 (표준 출력으로 인쇄) 실행하고 실행하여 Strawberry Perl 5.24.0에서 테스트

print f $h="Hello, world!"or die"Error writing \"$h\"$/"

(표준 오류로 인쇄 됨). 딸기를 사용하여 다른 오류를 테스트하는 방법을 모르지만 동일한 방식으로 처리 해야 합니다 ....


내가 알 수있는 한, 이것은 작동하지 않습니다. tio.run/nexus/bash#jY3NDoIwEITvfYq1IXCiiD83ys3Ei2/… (문자열에 쉼표가 없습니다.)
Dennis

귀하가 링크 한 페이지를 어떻게해야할지 모르겠습니다. 설명해 주시겠습니까? 또한 스크립트는 하나의 OS에서만 작동해야합니다. 쉼표를 추가하겠습니다. 감사.
msh210

출력 은 다른 뒤에 표시되어야 하며 다른 뒤에는 표시 Hello, world!되지 않아야 === 1 ===합니다. 디버그 아무것도 표시되지해야 후 === 1 ===Error writing "Hello, world!" 다른 후를. 나는 당신의 프로그램이없는 것을 알고 있어요 에이 TIO에 작동하지만 print f...원래의 프로그램이하지 않는 동안 쇼는 오류 메시지를 구성.
데니스

"Output"과 "Debug"는 내가 아는 한 아무것도 표시하지 않습니다. 또한 "Header"와 "Footer"섹션이 무엇인지 알지 못합니다. 그리고 TIO에 익숙하지 않지만 Strawberry Perl은 MS Windows에서 실행됩니다.
msh210

문자열을 변수에 저장한다는 아이디어 로 Dennis 에게 해답 을주었습니다 (아마도 그것을 보지 못했다고 생각했을 것입니다).
msh210

0

REXX, 111106 바이트

signal on notready
a='Hello, world!'
_=lineout(,a)
exit
notready:_=lineout('stderr','Error writing "'a'"')

이 프로그램은 'stderr'이라는 스트림이 있어야합니다. IBM 시스템에서는 그렇지 않을 것입니다.


0

C, 77 바이트

f(a){a="Error writing \"Hello, world!\"";write(1,a+15,13)-13&&write(2,a,29);}

전화

main(){f(1); return 0;}

어떤 플랫폼에서 이것을 테스트 했습니까? 파이프가 파손 된 경우 Linux에서는 작동하지 않습니다.
Dennis

0

R , 91 바이트

s="Hello, world!"
tryCatch(cat(s),error=function(e)cat('Error writing "','"',file=2,sep=s))

온라인으로 사용해보십시오!

cat(s,file=12)대신 대신 실행하여 오류를 시도 cat(s)했으며 stderr에 올바른 텍스트를 인쇄합니다. 이것은이다 invalid connection, 그렇지 않으면 오류가 발생합니다.


다른 출력 오류를 테스트하는 방법에 대한 아이디어가 있습니까?
JayCe
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.