{"id":4867,"date":"2021-07-17T00:01:16","date_gmt":"2021-07-17T07:01:16","guid":{"rendered":"https:\/\/c-for-dummies.com\/blog\/?p=4867"},"modified":"2021-07-24T08:10:10","modified_gmt":"2021-07-24T15:10:10","slug":"discovering-command-line-options-part-iv","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=4867","title":{"rendered":"Discovering Command Line Options, Part IV"},"content":{"rendered":"<p>Some command line switches stand alone. Others are followed by options, such as a starting value, filename, and other settings. The <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=4856\"><em>getopt()<\/em> function<\/a> processes these values along with the switches, providing you know the secret.<br \/>\n<!--more--><br \/>\nBefore revealing the secret (you can wait), know that a <em>switch-case<\/em> structure nested in a <em>while<\/em> loop is the best way to process multiple switches. The following listing shows how such a beast is assembled:<\/p>\n<h3><a href=\"https:\/\/github.com\/dangookin\/C-For-Dummies-Blog\/blob\/master\/2021_07_17-Lesson-a.c\" rel=\"noopener\" target=\"_blank\">2021_07_17-Lesson-a.c<\/a><\/h3>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n#include &lt;stdlib.h&gt;\r\n#include &lt;unistd.h&gt;\r\n\r\nint main(int argc, char *argv[])\r\n{\r\n    int r;\r\n\r\n    <span class=\"comments\">\/* suppress getopt()'s error message *\/<\/span>\r\n    opterr = 0;\r\n\r\n    while( (r=getopt(argc,argv,\"az\")) != -1 )\r\n    {\r\n        switch(r)\r\n        {\r\n            case 'a':\r\n                puts(\"-a option is activated\");\r\n                <span class=\"comments\">\/* do A option stuff here *\/<\/span>\r\n                break;\r\n            case 'z':\r\n                puts(\"-z option is activated\");\r\n                <span class=\"comments\">\/* do Z option stuff here *\/<\/span>\r\n                break;\r\n            case '?':\r\n                printf(\"'%c' is an invalid argument\\n\",optopt);\r\n                break;\r\n            default:\r\n                puts(\"Unknown argument\");\r\n        }\r\n    }\r\n\r\n    return(0);\r\n}<\/pre>\n<p>The program accepts two arguments, <code>-a<\/code> and <code>-z<\/code>, as shown at Line 12. They can be specified in any order, as shown by these sample runs:<\/p>\n<p><code>$ .\/a.out -a -z<br \/>\n-a option is activated<br \/>\n-z option is activated<br \/>\n$ .\/a.out -z -a<br \/>\n-z option is activated<br \/>\n-a option is activated<\/code><\/p>\n<p>You can even bunch them up:<\/p>\n<p><code>$ .\/a.out -az<br \/>\n-a option is activated<br \/>\n-z option is activated<br \/>\n$ .\/a.out -za<br \/>\n-z option is activated<br \/>\n-a option is activated<\/code><\/p>\n<p>Things get tricky for the <em>getopt()<\/em> function when a switch requires an option. (This is the secret part.) For example:<\/p>\n<p><code>$ .\/a.out -a 177<\/code><\/p>\n<p>Above, the <code>-a<\/code> switch requires an option, say the number of people who fully understand double pointers in C. To notify the <em>getopt()<\/em> function of such an option, suffix a colon to the switch&#8217;s character in the option string:<\/p>\n<p><code>getopt(argc,argv,\"a:z\")<\/code><\/p>\n<p>Above, the <code>-a<\/code> switch has an option but <code>-z<\/code> does not. The option is available immediately after the <em>getopt()<\/em> function reads the <code>-a<\/code>. It&#8217;s accessed as a string through the <code>optarg<\/code> global variable. So, when the option is a numeric value, you must convert it from a string to the proper data type.<\/p>\n<p>The following code processes an argument for the <code>-a<\/code> switch, but not the <code>-z<\/code> switch:<\/p>\n<h3><a href=\"https:\/\/github.com\/dangookin\/C-For-Dummies-Blog\/blob\/master\/2021_07_17-Lesson-b.c\" rel=\"noopener\" target=\"_blank\">2021_07_17-Lesson-b.c<\/a><\/h3>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n#include &lt;stdlib.h&gt;\r\n#include &lt;unistd.h&gt;\r\n\r\nint main(int argc, char *argv[])\r\n{\r\n    int r;\r\n\r\n    <span class=\"comments\">\/* suppress getopt()'s error message *\/<\/span>\r\n    opterr = 0;\r\n\r\n    while( (r=getopt(argc,argv,\"a:z\")) != -1 )\r\n    {\r\n        switch(r)\r\n        {\r\n            case 'a':\r\n                <span class=\"comments\">\/* -a has an argument *\/<\/span>\r\n                printf(\"-a option with argument %s\\n\",optarg);\r\n                <span class=\"comments\">\/* do A option stuff here *\/<\/span>\r\n                break;\r\n            case 'z':\r\n                puts(\"-z option is activated\");\r\n                <span class=\"comments\">\/* do Z option stuff here *\/<\/span>\r\n                break;\r\n            case '?':\r\n                printf(\"'%c' is an invalid argument\\n\",optopt);\r\n                break;\r\n            default:\r\n                puts(\"Unknown argument\");\r\n        }\r\n    }\r\n\r\n    return(0);\r\n}<\/pre>\n<p>In the <em>case<\/em> statements for option <code>-a<\/code> (starting at Line 16), the <code>optarg<\/code> variable is used in the <em>printf()<\/em> statement to output whatever argument follows <code>-a<\/code>. As with sample output shown previously, you can specify <code>-a<\/code> and <code>-z<\/code> in any order, but <code>-a<\/code> must have an argument, otherwise the <code>optarg<\/code> variable is misread. For example:<\/p>\n<p><code>$ .\/a.out -a -z<br \/>\n-a option with argument -z<\/code><\/p>\n<p>It&#8217;s up to your code to determine whether the proper argument is set &mdash; or even available. Otherwise the switches are misinterpreted and their purpose is lost.<\/p>\n<p>For multiple arguments with options, set a colon after each one in the <em>getopt()<\/em> function&#8217;s argument string. This operation can be tricky: You must test for each switch&#8217;s options. Otherwise a missing argument throws off the entire process.<\/p>\n<p>In <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=4878\">next week&#8217;s Lesson<\/a>, I cover the <em>getopt_long()<\/em> function, which processes full-word switches prefixed by a double-dash.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Use the <em>getopt()<\/em> function to read arguments supplied with a valid command line switch. <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=4867\">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-4867","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\/4867","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=4867"}],"version-history":[{"count":6,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/4867\/revisions"}],"predecessor-version":[{"id":4892,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/4867\/revisions\/4892"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=4867"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=4867"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=4867"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}