오류를 처리하는 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.