Напишите программу или функцию со следующими функциями:
- Программа / функция сначала пытается записать строку
Hello, world!
в стандартный поток вывода. (Никакие другие формы вывода не являются приемлемыми для этой задачи, так как основное внимание уделяется вводу / выводу, а не тривиальному поведению самой программы.) В зависимости от того, удалось ли это:- Если вывод завершился успешно
Hello, world!
, программа / функция завершается без каких-либо дополнительных действий. - Если из-за ошибки не удалось получить правильный вывод, программа / функция пытается записать строку
Error writing "Hello, world!"
в стандартный поток ошибок. (Для этой задачи вам не нужна обработка ошибок для самой обработки ошибок.)
- Если вывод завершился успешно
Разъяснения
Ваша программа / функция будет выполняться без ввода (если она не написана на языке, который абсолютно требует ввода для работы, и в этом случае она будет выполняться с максимально простым вводом).
При выводе вы также можете создать одиночный завершающий перевод строки, но это не обязательно.
Определение «ошибка записи в стандартный вывод», которое реализует ваша программа, должно обрабатывать как минимум следующие случаи как ошибки:
- Стандартный вывод не существует (т.
stdout
Е. Является закрытым дескриптором файла, дескриптор файла 1 не существует, или, однако, эти случаи переводятся на язык и ОС, которые вы используете); - Стандартный вывод со ссылкой на файл на диске, на котором не осталось свободного места;
- Стандартный выход подключается к другой программе, которая уже закрыла свой конец подключения.
и должен относиться как минимум к следующим случаям как к успеху (т.е. не к ошибке):
- Стандартный выход подключается к терминалу и
Hello, world!
отображается на экране. - Стандартный вывод подключается к файлу и
Hello, world!
записывается в файл.
Вы можете выбрать детали того, что считается ошибкой вывода, если это соответствует приведенным выше правилам.
- Стандартный вывод не существует (т.
Ваша программа / функция не должна аварийно завершать работу при возникновении любой из перечисленных выше ошибок. Вам решать, какой код выхода вы используете.
Ваша программа / функция не должна описывать природу обнаруженной ошибки в стандартном потоке ошибок; он должен просто напечатать указанную выше строку. Посторонний вывод при стандартной ошибке (например, предупреждения компилятора) допустим только в том случае, если он генерируется безоговорочно, независимо от того, возникла ошибка или нет.
Ваша программа должна работать только в одной операционной системе (хотя это должна быть та, в которой ошибки, перечисленные выше, имеют смысл; я постарался сделать их достаточно общими, чтобы работать в большинстве многозадачных операционных систем, но странные операционные системы вполне могут быть исключен из этого вызова). Если ваша программа не переносима, перечислите предположения, необходимые для ее выполнения, в заголовке вашей заявки.
Эта задача может быть невозможна на всех языках (не каждый язык позволяет программе обрабатывать ошибки вывода по-своему). Вам нужно будет выбрать язык там, где это возможно.
Убедитесь, что ваша программа / функция работает! Не просто доверяйте документации библиотечных функций делать то, что они говорят, что делают. Обработка ошибок простых функций вывода часто оказывается на практике нарушенной, даже если функции утверждают, что они обрабатывают ошибки в теории.
Контрольные примеры
Вот способ смоделировать каждое из условий ошибки, описанных выше bash
в Linux (вам не нужно использовать 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
Первые два теста являются детерминированными. Последнее не (это зависит от состояния гонки); в целях тестирования я рекомендую добавить задержку между запуском вашей программы и фактическим выходом к стандартному выводу, чтобы гарантировать, что условие гонки разрешается таким образом, что это приводит к ошибке.
Состояние победы
Это Код-гольфвызов, тем короче, тем лучше. Как (почти) всегда, мы измеряем длину программы в байтах.
sleep 1 < test; (sleep 2; your_program_here) > test
?Ответы:
Баш ,
7160 байтПопробуйте онлайн!
Как это работает
После сохранения
Hello, world!
в переменную h мы делаем следующее.Во-первых,
(echo $h)2>&-
попытки печатиHello, world!
в STDOUT.2>&-
требуется для предотвращения отображения сообщения об ошибке echo: write error: неверный дескриптор файла в случае сбоя записи. Поскольку запись в именованный канал, который не принимает ввод, приведет к уничтожению программы Bash с сигналом 13 (SIGPIPE), мы выполним команду в subshell ((...)
), поэтому будет уничтожен только подоболочка.Наконец, если печать в STDOUT не удалась, подоболочка завершится с ненулевым кодом состояния (141 для SIGPIPE, 1 для общей ошибки), поэтому
echo Error writing \"$h\">&2
печатает желаемое сообщение в STDERR.источник
Python 2 , 65 байт
Два байта могут быть сохранены путем печати одинарных кавычек.
Попробуйте онлайн!
источник
Zsh , 55 байтов
В отличие от своей кузины Баш, Зш отказывается умирать из-за сломанной трубы.
Попробуйте онлайн!
источник
C (gcc) ,
8786 байтПопробуйте онлайн!
Ungolfed
источник
puts
возвращает количество записанных байтов или -1 в случае ошибки, поэтому возвращает либо 14 (Hello World плюс перевод строки), либо -1 . (Это может зависеть от платформы, но именно так она себя ведет с glibc.)PowerShell, 80 байт
пояснил:
не удалось на самом деле попробовать это, когда он ошибается, но это определенно ~ должно ~ работать.
источник
Write-Host -ErrorAction Stop
или что-то в этом роде. Кроме того,throw
производит дополнительную отладочную информацию помимо строки, которую она должна напечатать, которая, кстати, должна иметь строчную букву W и двойные кавычки вокруг строки HW.Javascript,
7976 байтисточник
'Hello, world!'
, которая на один байт длиннее, чем вы используете. Кроме того, я полагаю, что назначениеa
внутри вызоваconsole.log
будет короче (1B) и удаление точки с запятой послеl.log(a)
сохранения другого байта.try{(l=console).log(a="Hello, world!")}catch(e){l.error('Error writing '+a)}
для 76 байтов. Сначалаconsole
назначаетсяl
, затем"Hello, world!'
назначаетсяa
, а затем выполняется.Perl 5, 51 байт
требует
-M5.01
, что бесплатноПротестировано в Strawberry Perl 5.24.0, запустив программу как есть (вывод на стандартный вывод) и запустив
(напечатано со стандартной ошибкой). Я не знаю, как проверять другие ошибки, используя Strawberry, но они должны обрабатываться одинаково…
источник
Hello, world!
после=== 1 ===
и ничего после остальных. Отладка не должна отображать ничего после=== 1 ===
иError writing "Hello, world!"
после остальных. Я знаю, что ваша программа не должна работать на TIO, ноprint f...
показывает предполагаемые сообщения об ошибках, в то время как оригинальная программа этого не делает.REXX,
111106 байтПрограмма полагается на наличие потока с именем 'stderr'. Это, вероятно, не будет иметь место в системах IBM.
источник
C 77 байт
для вызова
источник
R , 91 байт
Попробуйте онлайн!
Я попытался ошибиться, запустив его
cat(s,file=12)
вместоcat(s)
, и он напечатал правильный текст в stderr. Вinvalid connection
противном случае это ошибка.источник