エラーを処理するHello World


9

次の機能を持つプログラムまたは関数を記述します。

  • プログラム/関数は、最初に文字列Hello, world!を標準出力ストリームに書き込もうとします。(プログラム自体の些細な動作ではなく、I / Oに重点が置かれているため、この課題では他の形式の出力は受け入れられません。)成功した​​かどうかによって、次のようになります。
    • 出力に成功した場合Hello, world!、プログラム/関数はそれ以上動作せずに終了します。
    • エラーのために正しい出力を生成できなかった場合、プログラム/関数は文字列Error writing "Hello, world!"を標準エラーストリームに書き込もうとします。(この課題では、エラー処理自体にエラー処理は必要ありません。)

明確化

  • プログラム/関数は入力なしで実行されます(動作するために入力が絶対に必要な言語で記述されている場合を除きます。その場合、可能な限り単純な入力で実行されます)。

  • 出力を生成する場合、必要に応じて単一の末尾改行を生成することもできますが、これは必須ではありません。

  • プログラムが実装する「標準出力への書き込みエラー」の定義では、少なくとも以下のケースをエラーとして扱う必要があります。

    • 標準出力が存在しない(つまりstdout、閉じたファイルハンドルであり、ファイル記述子1が存在しない、またはこれらのケースが、使用している言語とOSに変換される)。
    • 空き領域が残っていないディスク上のファイルを参照する標準出力。
    • 接続の終わりをすでに閉じている別のプログラムに接続する標準出力。

    そして、少なくとも以下のケースを成功(すなわち、エラーではない)として扱う必要があります:

    • 標準出力は端末に接続され、Hello, world!画面に表示されます。
    • 標準出力はファイルに接続し、ファイルにHello, world!書き込まれます。

    上記のルールに準拠している限り、出力エラーとして数える詳細を選択できます。

  • 上記のエラー状況が発生しても、プログラム/関数がクラッシュすることはありません。使用する終了コードはあなた次第です。

  • プログラム/関数は、標準エラーストリームで発生したエラーの性質を記述しないでください。上で指定した文字列を出力するだけです。エラーが発生したかどうかに関係なく、標準エラー(コンパイラの警告など)の無関係な出力は、無条件に生成された場合にのみ有効です。

  • プログラムは1つのオペレーティングシステムでのみ動作する必要があります(ただし、上記のエラーが理にかなっている必要があります。ほとんどのマルチタスクコンシューマーオペレーティングシステムで動作するように十分に一般的なものにしようとしましたが、より奇妙なオペレーティングシステムでもかまいません。このチャレンジから除外されました)。プログラムが移植性がない場合は、提出するタイトルに、実行する必要がある前提条件をリストします。

  • このタスクは、すべての言語で可能であるとは限りません(すべての言語でプログラムがカスタムの方法で出力エラーを処理できるわけではありません)。可能な場合は言語を選択する必要があります。

  • プログラム/関数が機能することを確認してください!ライブラリ関数のドキュメントを信頼して、彼らが言うことを実行しないでください。単純な出力関数のエラー処理は、理論的には関数がエラーを処理すると主張している場合でも、実際には壊れていることがよくあります。

テストケース

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

最初の2つのテストケースは確定的です。最後はそうではありません(競合状態に依存します)。テストの目的で、エラーを公開する方法で競合状態を解決するために、プログラムの開始と実際の出力の間に標準出力に遅延を追加することをお勧めします。

勝利条件

これは挑戦なので、短いほど良いです。(ほぼ)いつものように、プログラムの長さをバイト単位で測定しています。


1
Windowsでこれをテストする方法があるかどうか知っていますか?最初の基準をテストすることはできますが、ディスクがいっぱいであるという部分はテストできません...
Stewie Griffin

競合状態を減らすために、使用できますsleep 1 < test; (sleep 2; your_program_here) > testか?
ニール

回答:


6

バッシュ71 60バイト

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

オンラインでお試しください!

使い方

Hello, world!変数hに保存した後、次のことを行います。

まず、STDOUT (echo $h)2>&-への出力を試みHello, world!ます。2>&-エラーメッセージを表示しないようにするために必要ですecho:書き込みエラー:書き込みが失敗した場合の不良ファイル記述子。入力を受け入れない名前付きパイプに書き込むと、シグナル13(SIGPIPE)でBashプログラム(...)が強制終了されるため、サブシェル()でコマンドを実行するため、サブシェルのみが強制終了されます。

最後に、STDOUTへの出力が失敗した場合、サブシェルはゼロ以外のステータスコード(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と改行)または-1を返します。(これはプラットフォーム固有の場合がありますが、これはglibcでの動作方法です。)
デニス

K&R2はエラーの場合、EOF [-1 praticically]を返すと言っています。または、すべて問題なければ負でない値
RosLuP

1
PPCGでは、言語はその実装によって定義され、gcc / glibcは私が言ったように動作します。
デニス

古い本を好む
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 2017

Afaict PowerShellは致命的な例外のみをキャッチするため、そのWrite-Host -ErrorAction Stopようなものが必要になります。また、は、出力throwする必要のある行の一部に追加のデバッグ情報を生成します。ちなみに、Wは小文字で、HW文字列は二重引用符で囲む必要があります。
デニス

@デニス追加のデバッグ情報が私を押しつぶしました、答えは今そこに更新されました。
colsw 2017

1

JavaScript、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)別のバイトを保存した後にセミコロンを削除するとします。
ルーク、

@ルークありがとう、それはかなり大きな間違いでした!
Matthew Roh

1
try{(l=console).log(a="Hello, world!")}catch(e){l.error('Error writing '+a)}76バイト。最初にconsoleに割り当てられl、次に"Hello, world!'に割り当てられてからa、実行されます。
ルーク

0

Perl 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\"$/"

(標準エラーに出力されます)。Strawberryを使用して他のエラーをテストする方法はわかりませんが、同じように処理する必要があります…。


私の知る限り、これは機能しません。tio.run/nexus/bash#jY3NDoIwEITvfYq1IXCiiD83ys3Ei2/…(文字列にもコンマがありません。)
Dennis

リンク先のページをどうするかわかりません。説明して頂けますか?また、スクリプトは1つのOSでのみ動作する必要があることに注意してください。そして、コンマを追加します。ありがとう。
msh210 2017

出力は他の後に表示さHello, world!=== 1 ===、後に何も表示されません。デバッグで=== 1 ===Error writing "Hello, world!"前後に何も表示されません 。あなたのプログラムはTIOで動作する必要がないことは承知していますがprint f...、元のプログラムでは動作しませんが、意図したエラーメッセージが表示されます。
デニス

「出力」と「デバッグ」はどちらも私が見る限り何も表示しません。また、「ヘッダー」セクションと「フッター」セクションがどうなっているのかわかりません。そして、私はTIOに完全に不慣れですが、Strawberry PerlはMS Windows上で実行されることに注意してください。
msh210 2017

変数に文字列を格納するという考えについてのDennisへのハットチップ(私がそこにそれを見なかったとしたらおそらく私はそれを考えたでしょうが)。
msh210 2017

0

REXX、111 106バイト

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では動作しません。
デニス

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 2018
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.