Все знают, что C - прекрасный, безопасный язык программирования высокого уровня. Однако перед вами, как за кодером, стоит следующая задача.
Напишите программу для добавления двух чисел.
- Входные данные: два целых числа через пробел.
- Выход: сумма двух чисел на входе.
Суть в том, что ваш код должен быть на 100% безопасным. Другими словами, он должен вести себя правильно, независимо от того, что ввод. Если на самом деле входные данные представляют собой два целых числа, разделенных пробелами, длина каждого из которых не превышает 100 цифр, он должен вывести сумму. В противном случае он должен вывести сообщение об ошибке и выйти безопасно.
Как тяжело это может быть в конце концов?
Общая слава будет дана патологическим входным случаям, которые нарушают ответы других людей :)
Код должен компилироваться без предупреждений, используя gcc -Wall -Wextra в Ubuntu.
Разъяснение.
- Ввод от стандартного ввода.
- Горизонтальный пробел - это только один пробел. Перед первым числом не должно быть ничего, и ввод должен завершаться либо новой строкой + EOF, либо просто EOF.
- единственный действительный ввод, указанный в расширенной форме Бэкуса-Наура , это:
NONZERODIGIT = "1" / "2" / "3" / "4" / "5" / "6" / "7" / "8" / "9" ПОЗИТИВЕНУМЕР = НЕЗЕРОДИГИТ * 98DIGIT NEGATIVENUMBER = "-" ПОЗИТИВЕНУМЕР NUMBER = NEGATIVENUMBER / POSITIVENUMBER / "0" VALIDINPUT = NUMBER SP NUMBER * 1LF EOF
- Сообщение об ошибке - одна буква «E», за которой следует новая строка.
- Код должен окончательно завершиться менее чем за 0,5 с, независимо от того, что ввод.
Ответы:
6610 байт (не унифицировано)
Программа "Хороший мальчик", отвечающая всем критериям. Использует дополнение 10 с для отрицательных чисел. Также включены тестовые ремни и контрольные примеры.
Вот несколько тестовых наборов и несколько тестовых примеров, с которых можно начать. Не стесняйтесь отрывать чрезмерное использование Perl. Система, на которой она была разработана, не имела современного bash.
Небольшой набор тестовых случаев:
источник
bc
отдельный ответ.289
РЕДАКТИРОВАТЬ : Этот код работает только для натуральных чисел. Правила изменились, так как я публикую этот ответ.
Нецензурная и прокомментированная версия:
источник
./tmp.c: In function ‘f’: ./tmp.c:3:1: warning: suggest parentheses around comparison in operand of ‘|’ [-Wparentheses] ./tmp.c:3:1: warning: suggest parentheses around comparison in operand of ‘|’ [-Wparentheses] ./tmp.c: In function ‘main’: ./tmp.c:3:1: warning: control reaches end of non-void function [-Wreturn-type]
(s>99|c<48|c>57)
на(s>99||c<48||c>57)
исправить это?442
Это довольно долго, поэтому я могу поиграть в гольф дальше в выходные. Предполагается, что ввод осуществляется из стандартного ввода, завершается EOF (без перевода строки), разделитель - это только один символ значения ASCII 32 (то есть
' '
символ).Сообщение об ошибке будет одним символом «E», за которым следует новая строка.
С добавлением новой строки и небольшим количеством отступов: (читаемая версия, так что не стесняйтесь пропустить здесь)
Версия для чтения (некоторые операторы немного изменены, чтобы сделать ее более читаемой, но то, что они делают, должно быть одинаковым):
goto fail;
Вещь здесь притворным Apple.Я использовал версию gcc
gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
, и предупреждений нет.источник
getchar()
всегда получает от stdin). Предполагается, что он завершается EOF без перевода строки . Вы можете проверить это, введя [1] [пробел] [1] [Ctrl + D] [Ctrl + D], илиecho -n '1 1' | program
633 байта
Программа "Плохой мальчик", которая отвечает половине задач. Злоупотребляет C, выдает много предупреждений, но работает ... вроде. Произвольная арифметика точности фактически выполняется
bc
.Unminified версия
источник