{"id":4878,"date":"2021-07-24T00:01:50","date_gmt":"2021-07-24T07:01:50","guid":{"rendered":"https:\/\/c-for-dummies.com\/blog\/?p=4878"},"modified":"2021-07-17T09:35:15","modified_gmt":"2021-07-17T16:35:15","slug":"discovering-command-line-options-part-v","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=4878","title":{"rendered":"Discovering Command Line Options, Part V"},"content":{"rendered":"<p>Somewhere along the line, shell commands developed longer, verbose versions of their original, short command line switches. So in addition to <code>-o<\/code> you also could use <code>--output<\/code>. These switches offer readability and are easier to remember. Alas, the <em>getopt()<\/em> function doesn&#8217;t process them, but its sibling function <em>getopt_long()<\/em> does.<br \/>\n<!--more--><br \/>\nThe <em>getopt_long()<\/em> function works like <em>getopt()<\/em>, but allows for switches longer than a single character. These verbose switches are prefixed by two dashes, which aren&#8217;t processed by <em>getopt()<\/em>. The longer switches can be unique or they can map to existing short switches. So your program can use both the <code>-o<\/code> and <code>--output<\/code> switches to set the same option; the user can specify either switch.<\/p>\n<p>The format for <em>getopt_long()<\/em> is the same as for <em>getopt()<\/em>, but with two additional arguments: the address of an <code>option<\/code> structure array and an integer <code>index<\/code> value. Here is the <em>man<\/em> page format:<\/p>\n<p><code>int getopt_long(int argc, char * const *argv, const char *optstring,<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;const struct option *longopts, int *longindex);<\/code><\/p>\n<p>The fourth option, <code><em>longopts<\/em><\/code>, is the address of an array of <code>option<\/code> structures. Each structure in the array contains four members that describe the long option:<\/p>\n<p><code>struct option {<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;char *name;<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;int has_arg;<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;int *flag;<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;int val;<br \/>\n};<\/code><\/p>\n<p><code><em>name<\/em><\/code> is a the option word. This string is the name only; the two dashes are supplied by the user at the command prompt.<\/p>\n<p><code><em>has_arg<\/em><\/code> is an <em>int<\/em> value: 0 or <code>no_argument<\/code> for options without arguments; 1 or <code>required_argument<\/code> for options that require an argument; and 2 or <code>optional_argument<\/code> for an optional argument. Values or the defined constants can be specified.<\/p>\n<p><code><em>flag<\/em><\/code> allows the <em>getopt_long()<\/em> function&#8217;s return value to be saved in a specific variable as opposed to being returned from the function directly. Otherwise, specify <code>NULL<\/code>.<\/p>\n<p>The <code><em>val<\/em><\/code> member is the value to return when the option is found. The <em>int<\/em> value can be the same as an existing, single-letter switch. This way you can map a long, verbose switch to an existing, shorter switch.<\/p>\n<p>Though the <em>man<\/em> page specifies a pointer to the <em><code>longopts<\/code><\/em> argument, setting the array&#8217;s name is sufficient. The last structure in the array is filled with zeros, which is how the function knows it&#8217;s read them all. (See the sample code below.)<\/p>\n<p>Unlike the <em>getopts()<\/em> function, which is defined in the <code>unistd.h<\/code> header file, <em>getopts_long()<\/em> is defined in the <code>getopt.h<\/code> header file.<\/p>\n<p>In the sample code below, the program accepts switches <code>-a<\/code>, <code>--alpha<\/code>, <code>--greek<\/code>, and <code>-z<\/code>. The <code>-a<\/code> and <code>--alpha<\/code> switches represent the same option:<\/p>\n<h3><a href=\"https:\/\/github.com\/dangookin\/C-For-Dummies-Blog\/blob\/master\/2021_07_24-Lesson.c\" rel=\"noopener\" target=\"_blank\">2021_07_24-Lesson.c<\/a><\/h3>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n#include &lt;getopt.h&gt;\r\n\r\nint main(int argc, char *argv[])\r\n{\r\n    int r;\r\n    struct option args[3] = {\r\n        { \"alpha\", 0, NULL, 'a' },\r\n        { \"greek\", 0, NULL, 'g' },\r\n        { 0, 0, 0, 0 }\r\n    };\r\n\r\n    <span class=\"comments\">\/* supress the default error message *\/<\/span>\r\n    opterr = 0;\r\n\r\n    <span class=\"comments\">\/* configure long option arguments *\/<\/span>\r\n\r\n    while( (r=getopt_long(argc,argv,\"az\",args,0)) != -1 )\r\n    {\r\n        switch(r)\r\n        {\r\n            case 'a':\r\n                <span class=\"comments\">\/* -a or --alpha argument *\/<\/span>\r\n                puts(\"Option -a or --alpha is set\");\r\n                break;\r\n            case 'g':\r\n                <span class=\"comments\">\/* --greek argument *\/<\/span>\r\n                puts(\"The --greek argument is set\");\r\n                break;\r\n            case 'z':\r\n                <span class=\"comments\">\/* -z argument *\/<\/span>\r\n                puts(\"Option -z is set\");\r\n                break;\r\n            case '?':\r\n                printf(\"Inavlid option: %c\\n\",optopt);\r\n                break;\r\n            default:\r\n                puts(\"Unkonwn argument\");\r\n        }\r\n    }\r\n\r\n    return(0);\r\n}<\/pre>\n<p>The <em>getopt_long()<\/em> function appears at Line 18, embedded in the <em>while<\/em> loop&#8217;s condition. The function&#8217;s fourth argument is <code>args<\/code>, which references the <code>args[]<\/code> array of <code>option<\/code> structures defined at Line 7. <\/p>\n<p>Long argument <code>\"alpha\"<\/code> is defined in the first structure in the <code>args[]<\/code> array at Line 8. Structure member <code>'a'<\/code> is the value returned when <code>--alpha<\/code> is specified on the command line. This value is caught with the <em>case<\/em> statement at Line 22.<\/p>\n<p>Long argument <code>\"greek\"<\/code> is defined in the structure at Line 9. It returns argument <code>'g'<\/code>, caught at Line 26.<\/p>\n<p>At Line 10, the final structure in the array is filled with zeros.<\/p>\n<p>Here are some sample runs:<\/p>\n<p><code>$ .\/a.out -a --greek<br \/>\nOption -a or --alpha is set<br \/>\nThe --greek argument is set<br \/>\n$ .\/a.out -a --greek -z<br \/>\nOption -a or --alpha is set<br \/>\nThe --greek argument is set<br \/>\nOption -z is set<br \/>\n$ .\/a.out -g<br \/>\nInavlid option: g<\/code><\/p>\n<p>Long or short, the <em>getopt()<\/em> and <em>getopt_long()<\/em> functions help your code process command line switches. Uses these functions is easier than cobbling together your own loops and whatnot, especially when your program requires a variety of switches.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>To read more verbose command line switches, use the <em>getopt_long()<\/em> function. <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=4878\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[],"class_list":["post-4878","post","type-post","status-publish","format-standard","hentry","category-main"],"_links":{"self":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/4878","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=4878"}],"version-history":[{"count":8,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/4878\/revisions"}],"predecessor-version":[{"id":4890,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/4878\/revisions\/4890"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=4878"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=4878"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=4878"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}