Когда я пишу инструменты для CLI UNIX, как мне заставить программу распечатывать справку и / или использование?
Я обычно использую fprintf(stderr, "help text here");
, но есть несколько проблем с этим.
- Во-первых, я не уверен, стоит ли мне пользоваться
stderr
. Это нормально, или я должен использоватьstdout
? - Как вы можете себе представить, текст справки довольно длинный, в зависимости от того, сколько опций у инструмента. Теперь я обычно просто ставлю несколько
"strings like that\n"
во второй параметр. Это, однако, наполняет мой исходный код пятьдесят или более строк текста справки. Это нелегко сделать вообще. Что я должен сделать вместо этого? - Когда инструмент написан не на C или C-подобном языке, я, как правило, использую здесь-документы, где это возможно (особенно заметно на Perl). Я не могу использовать это в C, но есть ли что-то подобное, что я мог бы использовать?
- Я подумывал о том, чтобы положить его
headerfile.h
внутрь#define HELP "help text here"
, я никогда не видел его в дикой природе, не знаю, стоит ли мне это использовать.
В идеале я мог бы поместить текст во внешний файл и включить его. Использование #include
для этого кажется неправильным, хотя. Что мне тогда делать?
Идея состоит в том, чтобы иметь справочный текст, которым легко управлять. Иметь его внутри исходного кода не очень удобно.
Ответы:
Вдохнови себя внутренностями своей целевой платформы
Посмотрите на исходный код BSD. Например, вот:
usage(void)
для/usr/bin/uname
инструмента NetBSD [ источник ]:usage(void)
для NetBSD/usr/bin/telnet
[ источник ]usage(void)
для OpenBSD/bin/ls
[ источник ]Посмотрите на альтернативы
И решить для себя, лучше они или хуже. Вы можете использовать Google CodeSearch для поиска других, например:
Как видите, разные стили между этими и BSD-системами интегрированы в инструменты, перечисленные выше. Это не значит, что вы должны следовать одному или другому. Но обычно хорошо осмотреться и согласиться на последовательное решение.
Нестандартное решение для 50 строк помощи ...
Если вам не нравится избегать 50 строк текста, вы можете просто прочитать справку из текстового файла (в виде обычного текста или, возможно, напрямую проанализировать
man
исходный текст, если вы его создали). Я считаю, что это довольно элегантный способ (как вы можете даже посмотреть текстовый документ), однако для основных системных программ, которые сделали бы их по сути небезопасными и привели бы к точке отказа. Другие люди будут утверждать, что это тяжело для сообщенияusage
илиhelp
, но это не так, как если бы они назывались в быстрых коротких циклах ...Если есть сомнения, следуйте за гигантами.
источник
Я использую
stdout
, потому что помощь не является ошибкой.Если это долгая помощь в C, я попытаюсь подражать здесь документам:
Но большую часть времени я пишу
man
страницу, используяnroff -man
специальные теги. Справка в приложении просто заключается в обращении к этойman
странице.источник
stdlog
?stdlog
стандарт C?cin
,cout
,cerr
иclog
), так что я предполагаю , что я думал , чтоstdlog
было в стандарте C. Виноват.Если я бы тебя я просто открыл источники
grep
,tail
,cat
,your_other_favorite_unix_shell_command
чтобы увидеть , как это делается там. Я уверен, что их пути хорошо продуманы и могут поддерживаться многими людьми.О
stderr
илиstdout
. Это действительно просто, если есть ошибка - пишитеstderr
, если это просто информация -stdout
. Например, если я запускаю ваш инструмент с неправильными параметрами, вы можете отобразить ошибку, скажемUse --help for usage
, эта принадлежитstderr
. Если я запускаю ваш инструмент с верной опцией--help
, пожалуйста, используйтеstdout
.Если вы предпочитаете, чтобы рядом с вашим кодом не было длинных строк справки, не делайте этого. #define в заголовочном файле прекрасно, но это личное предпочтение. Если бы мне пришлось читать код инструмента командной строки, я бы предпочел, чтобы его строка справки находилась внутри файла, который обрабатывает параметры, предоставленные пользователем.
источник
Я использую библиотеку GNU Getopts . Для примера с помощью см. Этот пример проекта , в частности, основной метод в нижней части parser.y .
Поскольку он заключен в фигурные скобки, редактор vim, который я использую, может складывать строки, и я даже не замечаю их, когда мне это не нужно.
источник
Если я использую C или предпочитаю не зависеть от библиотек Boost, то я придерживаюсь GNU
getopt
. В противном случае я предпочитаю параметры программы Boost, которые помогают печатать автоматически.Я также считаю, угадывание правильного варианта одним из лучших методов, когда дело доходит до обработки опций. Я узнал об этом из Git и теперь использую то же самое в моих проектах. Он в основном использует расстояние Дамерау – Левенштейна для печати лучших совпадений, если пользователь вводит какую-то неизвестную опцию командной строки.
Я написал небольшую статью об этом, которую вы можете использовать в качестве примера.
Надеюсь, поможет :)
источник
Очевидно, что написание дырочной страницы в коде cout << или printf () обременительно, особенно если вам нужно изменить и заново заполнить абзацы. Следовательно, это хорошая идея, чтобы отредактировать этот текст в отдельном файле, используя, например, emacs, где вы можете легче отформатировать текст.
Затем вы можете использовать следующий скрипт sed для преобразования этого текстового файла в допустимый файл заголовка C:
Затем, после #include -ing вашего заголовочного файла в ваш исходный код, вы можете просто написать свой текст, используя
источник