{"id":4823,"date":"2021-06-26T00:01:50","date_gmt":"2021-06-26T07:01:50","guid":{"rendered":"https:\/\/c-for-dummies.com\/blog\/?p=4823"},"modified":"2021-07-03T07:09:47","modified_gmt":"2021-07-03T14:09:47","slug":"discovering-command-line-options-part-i","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=4823","title":{"rendered":"Discovering Command Line Options, Part I"},"content":{"rendered":"<p>The <em>getopt()<\/em> function is perhaps one of the most versatile functions I&#8217;ve encountered in my C programming journey. It plucks out switches from the list of command line arguments, processing valid ones and spitting out the trash. It&#8217;s really quite amazing, but it&#8217;s not without its quirks.<br \/>\n<!--more--><br \/>\nBefore I knew about <em>getopt()<\/em>, I coded my own routines to parse command line switches. These typically involved a loop that churned through each argument, comparing it with my slate of valid arguments.<\/p>\n<p>This example is from my version of the <em>robots<\/em> game. It processes a single argument, which can be any of these options:<\/p>\n<p><code>--about<br \/>\n--help<br \/>\n-h<br \/>\n--startinglevel=<em>n<\/em><br \/>\n-s<em>n<\/em><\/code><\/p>\n<p>Here is the code:<\/p>\n<pre class=\"screen\">\r\nvoid searchArgs(int count, char *strings[])\r\n{\r\n    char *s;\r\n\r\n    if(count == 1) return;\r\n\r\n    count--;\r\n\r\n<span class=\"comments\">\/* Check for About this program *\/<\/span>\r\n    if( strcmp(strings[count],\"--about\") == 0)\r\n        showAbout();\r\n\r\n<span class=\"comments\">\/* Check for Help *\/<\/span>\r\n    if( strcmp(strings[count],\"--help\") == 0)\r\n        showHelp();\r\n    if( strcmp(strings[count],\"-h\") == 0)\r\n        showHelp();\r\n\r\n<span class=\"comments\">\/* Check for Starting Level option *\/<\/span>\r\n    if( strncmp(strings[count],\"--startinglevel=\",16) == 0)\r\n    {\r\n        s = strings[count];\r\n        s += 16;\r\n        setStarting(strtol(s,NULL,10));\r\n        return;\r\n    }\r\n    if( strncmp(strings[count],\"-s\",2) == 0)\r\n    {\r\n        s = strings[count];\r\n        s += 2;\r\n        setStarting(strtol(s,NULL,10));\r\n        return;\r\n    }\r\n\r\n<span class=\"comments\">\/* All options exhausted *\/<\/span>\r\n    puts(\"Unknown or misspelled argument\");\r\n    showHelp();\r\n}<\/pre>\n<p>If the user specified some invalid argument, a warning message is output. This method represents a simple, brute force way to process the single, valid switch. The heavy lifting is done by the <em>strcmp()<\/em> function. Other functions referenced in the snippet carry out the tasks the switches activate.<\/p>\n<p>The following snippet is from another program. It uses a <em>while<\/em> loop to process multiple valid switches:<\/p>\n<pre class=\"screen\">\r\n\/* check for args *\/\r\nif(argc)\r\n{\r\n    count = argc;\r\n    while(count--)\r\n    {\r\n        if(strcmp(argv[count],\"--verbose\") == 0)\r\n            verbose = TRUE;\r\n        if(strcmp(argv[count],\"-v\") == 0)\r\n            verbose = TRUE;\r\n        if(strcmp(argv[count],\"--version\") == 0)\r\n        {\r\n            version_info();\r\n            return 99;\r\n        }\r\n        if(strcmp(argv[count],\"--help\") == 0)\r\n        {\r\n            help_message();\r\n            return 99;\r\n        }\r\n    }\r\n}<\/pre>\n<p>This approach again uses the <em>strcmp()<\/em> function to test for and confirm a valid argument. Options are set, such as <code>verbose = TRUE<\/code>, for each scan. Duplicate and conflicting arguments aren&#8217;t detected, however.<\/p>\n<p>Imagine what horrors would confront you if your program required even more command line switches, including switches with options?<\/p>\n<p>Well, don&#8217;t imagine anything. That&#8217;s because the <em>getopt()<\/em> function, as well as its brother <em>getopt_long()<\/em>, can easily process all the command line switches your program needs. Here is its <em>man<\/em> page format:<\/p>\n<p><code>int getopt(int argc, char * const argv[], const char *optstring);<\/code><\/p>\n<p>The familiar <em>main()<\/em> function arguments, <code>argc<\/code> and <code>argv[]<\/code> are used in <em>getopt()<\/em>, which is a blessing. The third argument, <code>optstring<\/code>, is a string consisting of valid switches. Specifically, the switch letters, which are case-sensitive.<\/p>\n<p>The return value is the tricky part. It&#8217;s an integer code from a matching character in the <code>optstring<\/code> string. If -1 is returned, nothing matched. Further, the function outputs its own error message for an illegal (unspecified) option.<\/p>\n<p>This <em>getopt()<\/em> function requires you include the <code>unistd.h<\/code> header file, lest the compiler get cross with you.<\/p>\n<p>Like I wrote earlier, this function is quirky. It helps to run a few sample programs to review how it works. Once you understand what it does, however, you&#8217;ll be delighted with its versatility. More details are coming in <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=4829\">next week&#8217;s Lesson<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>How does your program know which command line options have been specified? <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=4823\">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-4823","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\/4823","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=4823"}],"version-history":[{"count":8,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/4823\/revisions"}],"predecessor-version":[{"id":4863,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/4823\/revisions\/4863"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=4823"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=4823"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=4823"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}