Hataları işleyen merhaba dünya


9

Aşağıdaki işlevselliğe sahip bir program veya işlev yazın:

  • Program / işlev önce dizeyi Hello, world!standart çıktı akışına yazmaya çalışır . (Odak, programın kendisinin önemsiz davranışından çok G / Ç üzerinde olduğundan, bu zorluk için başka hiçbir çıktı biçimi kabul edilemez.) Başarılı olup olmadığına bağlı olarak:
    • Çıktı almada başarılı olursa Hello, world!, program / işlev başka bir davranış olmadan çıkar.
    • Bir hata nedeniyle doğru çıktıyı üretemezse, program / işlev dizeyi Error writing "Hello, world!"standart hata akışına yazmaya çalışır . (Bu zorluğun amaçları doğrultusunda, hata işlemenin kendisi için hata işlemeye ihtiyacınız yoktur.)

Açıklamalar

  • Programınız / işleviniz giriş olmadan çalıştırılacaktır (kesinlikle çalışması için giriş gerektiren bir dilde yazılmadığı sürece, bu durumda mümkün olan en basit girişle çalıştırılacaktır).

  • Çıktı üretirken, isterseniz tek bir sondaki yeni satır da üretebilirsiniz, ancak bunu yapmak zorunlu değildir.

  • Programınızın uyguladığı "standart çıktıya yazma hatası" tanımı, en azından aşağıdaki durumları hata olarak ele almalıdır:

    • Standart çıktı yok (örn. stdoutKapalı bir dosya tanıtıcısı, dosya tanımlayıcısı 1 yok veya bu durumlar kullandığınız dil ve işletim sistemine çevriliyor);
    • Diskte boş alan kalmamış bir dosyaya gönderme yapan standart çıktı;
    • Bağlantının sonunu zaten kapatmış olan başka bir programa bağlanan standart çıkış.

    ve en azından aşağıdaki durumları başarı olarak ele almalıdır (yani bir hata değil):

    • Standart çıkış bir terminale bağlanır ve Hello, world!ekranda görüntülenir.
    • Standart çıktı bir dosyaya bağlanır ve dosyaya Hello, world!yazılır.

    Yukarıdaki kurallarla tutarlı olduğu sürece, çıkış hatası olarak sayılanların ayrıntılarını seçebilirsiniz.

  • Programınız / işleviniz, yukarıda listelenen hata durumlarıyla karşılaştığında çökmemelidir. Hangi çıkış kodunu kullandığınıza bağlı.

  • Programınız / işleviniz, standart hata akışında karşılaşılan hatanın niteliğini tanımlamamalıdır; sadece yukarıda belirtilen dizeyi yazdırmalıdır. Standart hatada harici çıktı (örneğin derleyici uyarıları) yalnızca bir hatayla karşılaşılıp karşılaşılmadığına bakılmaksızın koşulsuz olarak üretilmesi durumunda yasaldır.

  • Programınızın yalnızca bir işletim sistemi üzerinde çalışması gerekir (yukarıda listelenen hataların mantıklı olduğu bir sistem olsa da; Çoğu çok görevli tüketici işletim sistemlerinde çalışacak kadar genel tutmaya çalıştım, ancak garip işletim sistemleri iyi olabilir bu zorluğun dışındadır). Programınız taşınamıyorsa, başvurunuzun başlığında çalışması gereken varsayımları listeleyin.

  • Bu görev her dilde mümkün olmayabilir (her dil bir programın çıktı hatalarını özel bir şekilde işlemesine izin vermez). Mümkün olan yerlerde bir dil seçmeniz gerekecek.

  • Programınızın / fonksiyonunuzun çalıştığından emin olun! Sadece kütüphane fonksiyonlarının dokümantasyonuna, söylediklerini yapmak için güvenmeyin. Basit çıktı fonksiyonlarının hata yönetimi, fonksiyonlar teoride hataları ele aldığını iddia etseler bile pratikte kırılır.

Test senaryoları

bashLinux'ta yukarıdaki hata koşullarının her birini simüle etmenin bir yolu (Linux kullanmak zorunda değilsiniz, ancak muhtemelen bunu test etmek için en kolay sistemdir):

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

İlk iki testis belirleyicidir. Sonuncusu (bir yarış durumuna dayanır); test amacıyla, yarış durumunun hatayı ortaya çıkaracak şekilde çözülmesini sağlamak için programınızın başlangıcı ile gerçek çıktı arasında bir gecikme eklemenizi öneririm.

Zafer koşulu

Bu bir meydan okuma, çok daha kısa daha iyidir. Her zaman olduğu gibi, programın uzunluğunu bayt cinsinden ölçüyoruz.


1
Bunu Windows'ta test etmenin bir yolu olup olmadığını biliyor musunuz? İlk kriteri test edebilirim, ancak diskin dolu olduğu kısmı değil ...
Stewie Griffin

Yarış durumunu azaltmak için kullanabilir sleep 1 < test; (sleep 2; your_program_here) > testmisiniz?
Neil

Yanıtlar:


6

Bash , 71 60 bayt

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

Çevrimiçi deneyin!

Nasıl çalışır

HHello, world! değişkenine kaydettikten sonra aşağıdakileri yaparız.

İlk olarak, STDOUT'a (echo $h)2>&-yazdırmaya çalışır Hello, world!. 2>&-hata mesajının görüntülenmesini önlemek için gereklidir echo: write error: Yazma başarısız olursa hatalı dosya tanıtıcısı . Girdiyi kabul etmeyen adlandırılmış bir boruya yazmak, Bash programını sinyal 13 (SIGPIPE) ile öldüreceğinden, komutu bir alt kabuk ( (...)) içinde yürütürüz , böylece yalnızca alt kabuk öldürülür.

Son olarak, STDOUT'a yazdırma başarısız olursa, alt kabuk sıfırdan farklı bir durum koduyla (SIGPIPE için 141, genel bir hata için 1) çıkacaktır, bu nedenle echo Error writing \"$h\">&2istenen mesajı STDERR'a yazdırır.



1

Zsh , 55 bayt

h=Hello,\ world!
2>&-<<<$h||<<<'Error writing "'$h\">&2

Kuzeni Bash'in aksine Zsh, kırık bir boru yüzünden ölmeyi reddediyor.

Çevrimiçi deneyin!


1

C (gcc) , 87 86 bayt

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

Çevrimiçi deneyin!

Ungolfed

#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);
}

dönüşün ne getireceğini nereden biliyorsun? burada tüm iyi olmak için> = 0 diyor ...
RosLuP

putsyazılan bayt sayısını veya bir hata durumunda -1 değerini döndürür, böylece 14 (Hello World plus newline) veya -1 değerini döndürür . (Bu platforma özgü olabilir, ancak glibc ile böyle davranır.)
Dennis

K & R2 hata durumunda EOF [-1 pratik] döndürdüğünü söylüyor; veya eğer
tamamsa

1
PPCG'de, diller uygulamalarıyla tanımlanır ve gcc / glibc benim söylediğim gibi davranır.
Dennis

eski kitabı tercih ediyorum
RosLuP

1

PowerShell, 80 Bayt

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

açıkladı:

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"""
}

hata verdiğinde bunu gerçekten denemedim, ama kesinlikle ~ çalışmalı.


Hata mesajı STDERR'a yazılmalıdır . İlk yazma denemesi sırasında bir hata oluşursa STDOUT'a yazmak mümkün değildir.
Dennis

@Dennis için teşekkürler, orada güncellenen, soruyu tam olarak okumadım.
colsw

Afaict PowerShell yalnızca ölümcül istisnaları yakalar, bu yüzden buna Write-Host -ErrorAction Stopveya buna benzer bir şeye ihtiyacınız olur . Ayrıca, throwyazdırması gereken satır dışında ek hata ayıklama algoritması üretir, bu arada HW dizesinin etrafında küçük bir W ve çift tırnak bulunmalıdır .
Dennis

@Dennis ek hata ayıklama bilgileri beni ezdi, cevap şimdi orada güncellendi.
colsw

1

Javascript, 79 76 bayt

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

Çıkarmanız gereken dizenin 'Hello, world!', kullandığınızdan bir bayt daha uzun olduğunu unutmayın. Ayrıca, açağrının içine atamanın console.logdaha kısa (1B) olacağını ve l.log(a)başka bir bayt kaydedildikten sonra noktalı virgül kaldırıldığını varsayalım .
Luke

@ Teşekkürler, Bu oldukça büyük bir hataydı!
Matthew Roh

1
try{(l=console).log(a="Hello, world!")}catch(e){l.error('Error writing '+a)}76 bayt için. Önce, consoleatandı l, sonra "Hello, world!'atandı ave sonra yürütüldü.
Luke

0

Perl 5, 51 bayt

gerektirir -M5.01, ücretsiz

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

Programı olduğu gibi çalıştırarak (standart çıktıya yazdırılmış) ve çalıştırarak Çilek Perl 5.24.0'da test edilmiştir

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

(standart hataya yazdırılmıştır). Çilek kullanarak diğer hatalar için nasıl test bilmiyorum, ama aynı ele alınmalıdır ….


Anlayabildiğim kadarıyla, bu işe yaramıyor. tio.run/nexus/bash#jY3NDoIwEITvfYq1IXCiiD83ys3Ei2/… (Dize de virgül eksik.)
Dennis

Bağlantı kurduğunuz sayfadan ne yapacağımı bilmiyorum; açıklayabilir misiniz lütfen? Ayrıca, komut dosyasının yalnızca bir işletim sisteminde çalışması gerektiğini unutmayın. Ve virgül ekleyeceğim; Teşekkürler.
msh210

Çıktı göstermesi gerekir Hello, world!sonra === 1 ===başkaları sonra ve hiçbir şey. Hata ayıklama diğerlerinden sonra === 1 ===ve Error writing "Hello, world!"sonra hiçbir şey göstermemelidir. Ben program olmadığını farkındayım zorunda TIO çalışma, ancak print f...orijinal programı yok iken gösterileri hata mesajları niyetindeydi.
Dennis

"Çıktı" ve "Hata Ayıkla" ifadelerinin her ikisi de benim gördüğüm kadarıyla hiçbir şey göstermiyor. "Üstbilgi" ve "Altbilgi" bölümlerinin ne olması gerektiğini de bilmiyorum. Ve TIO'ya tamamen aşina değilim, ancak Çilek Perl'in MS Windows'ta çalıştığını unutmayın.
msh210

Dizeyi bir değişkende saklamak fikri için Dennis'e şapka ucu (muhtemelen orada görmemiş olsaydım düşünürdüm).
msh210

0

REXX, 111 106 bayt

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

Program, 'stderr' adı verilen bir akış olmasına dayanır. Bu muhtemelen IBM sistemlerinde geçerli olmayacaktır.


0

C, 77 bayt

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

çağrı için

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

Bunu hangi platformda test ettiniz? Kırık bir boru ile karşılaşıldığında Linux üzerinde çalışmaz.
Dennis

0

R , 91 bayt

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

Çevrimiçi deneyin!

Bunun cat(s,file=12)yerine çalıştırarak hata yapmayı denedim ve stderr'e cat(s)doğru metni yazdırıyor. invalid connectionAksi takdirde bu bir hatadır.


Diğer çıktı hatalarını nasıl test edeceğiniz hakkında bir fikriniz var mı?
JayCe
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.