When writing tools for the CLI of UNIX, how should I make the program print out help and/or usage?

I usually use fprintf(stderr, "help text here");, but there are several issues with that.

  • First, I'm not sure, whether I should use stderr. Is that OK, or should I use stdout?
  • As you can imagine, the help text is quite long, depending on how many options the tool has. Now, I usually, just put several "strings like that\n" in the second parameter. This however, fills my source code with fifty or more lines of help text. It is not easy manageable at all. What should I do instead?
  • When a tool is not written in C or a C-like language, I tend to use here-docs where possible (most prominently with Perl). I can't use that in C, but is there something like that, that I could use?
  • I was considering putting it in a headerfile.h inside a #define HELP "help text here", I've never seen it in the wild, don't know whether I should actually use that.

Ideally, I could put the text in an external file, and include it. Using #include for that seems wrong, though. What should I do then?

The idea is, to have a help text, that is easily manageable. Having it inside the source code isn't really convenient.

  • 1
    What's so bad about 50 lines in your source code? Just put it at the end. It's not like you're going to have to mess with it on a regular basis. Feb 28, 2012 at 23:40
  • 2
    @whatsisname usage, help for normal and longopts. I end up having around 200 lines of strings in the sourcode. Aside from that, I just don't think this is best practice, etc. There must be a more efficient way of putting in help texts, etc.
    – polemon
    Feb 28, 2012 at 23:58

6 Answers 6


Inspire yourself from your target platform's internals

Have a look at the BSD's source code. For instance, here are the:

  • usage(void) for NetBSD's /usr/bin/uname tool [source]:

        fprintf(stderr, "usage: uname [-amnprsv]\n");
  • usage(void) for NetBSD's /usr/bin/telnet [source]

  • usage(void) for OpenBSD's /bin/ls [source]

Have a look at alternatives

And decide for yourself whether they're better or worse. You can use Google CodeSearch to find others, like:

As you can see, different style between these and the BSD systems integrated tools listed above. It doesn't mean you have to follow one or the other. But usually it's good to look around, and settle for the consistent solution.

A non-standard solution to the 50 lines of help...

If you don't like to avoid 50 lines of text, you could simply read the help from a text file (in plain text, or maybe directly parse the man's source if you created one). I find that a rather elegant way (as you can even look up the text doc), however for core systems programs that would make them inherently unsafe and introduce a point of failure. Other people will argue it's heavy for a usage or help message, but it's not like these are called in fast tight loops...

When in doubt, follow the giants.


I use stdout, because a help is not an error.

If this is a long help in C, I try to mimic here-docs:

printf("This is the help for MyWonderfulApp\n"
       "Options are:\n"
       "    --help: display what you are reading now\n"
       "    --quiet: output nothing\n");

But most of the time I write a man page using nroff -man dedicated tags. The in-app help simply consists in refering to that man page.

  • But help is not necessarily desirable standard output, is it? How about stdlog?
    – greyfade
    Dec 5, 2013 at 20:23
  • @greyfade: Is stdlog standard C?
    – mouviciel
    Dec 5, 2013 at 20:39
  • @mouviciel: ... I thought it was. I guess not. C++ has a related standard stream (cin, cout, cerr, and clog), so I guess I thought stdlog was in the C standard. My bad.
    – greyfade
    Dec 5, 2013 at 21:27

If I'd be you I'd just opened up sources of grep, tail, cat, your_other_favorite_unix_shell_command to see how it's done there. I'm pretty sure their ways are pretty well thought out and can be maintained by many people.

About stderr or stdout. It's really simple, if there's an error - write to stderr, if it's just info - stdout. For example, if I run your tool with wrong options, you might want to display an error, say Use --help for usage, this one belongs in stderr. If I run your tool with a valid option --help, please use stdout.

If it's your preference not to have long help strings near your code, don't. #define in a header file is perfectly fine, but it's really a personal preference. If I had to read the code of a command line tool I'd prefer its help string to be inside a file that handles options supplied by the user.

  • 2
    That doesn't answer his question.
    – Mavrik
    Feb 29, 2012 at 8:39
  • Hm, what's up with the minus-ing? What for? Feb 29, 2012 at 9:35
  • @Mavrik: the first paragraph does.
    – haylem
    Feb 29, 2012 at 9:45

I use the gnu getopts library. For an example with help, see this sample project, specifically the main method at the bottom of parser.y.

Since it is wrapped in curly braces, the vim editor I use can fold the lines together, and I don't even notice them when I don't need to.


If I use C or prefer not to depend on Boost libraries, then I stick with GNU getopt. Otherwise I prefer Boost Program Options which prints help automatically.

I also consider guessing the right option one of the best practices when it comes to options handling. I learned it from Git and now use the same in my projects. It basically uses Damerau–Levenshtein distance to print best matches if user enters some unknown command line option.

I wrote a little article about this that you can use as an example.

Hope it helps :)


Obviously, writing a hole page in cout << or printf() code is cumbersome, particularly if you need to change and re-fill your paragraphs. Hence, it is obviously a good idea to edit that text in a separate file, using for example emacs where you can more easily format your text.

Then you can use the following sed script to convert that text file into a legal C header file:

const char *helpStr = 

Then, upon #include-ing your header file into your source code, you can simply write out your text using

cout << helpStr;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.