{"id":2804,"date":"2018-04-03T20:00:01","date_gmt":"2018-04-03T18:00:01","guid":{"rendered":"http:\/\/mariusbancila.ro\/blog\/?p=2804"},"modified":"2018-04-20T10:26:34","modified_gmt":"2018-04-20T08:26:34","slug":"parsing-command-line-arguments-in-cpp-with-clara","status":"publish","type":"post","link":"https:\/\/mariusbancila.ro\/blog\/2018\/04\/03\/parsing-command-line-arguments-in-cpp-with-clara\/","title":{"rendered":"Parsing command line arguments in C++ with Clara"},"content":{"rendered":"<p>In a <a href=\"http:\/\/mariusbancila.ro\/blog\/2018\/03\/29\/writing-cpp-unit-tests-with-catch2\/\">previous post<\/a>, I wrote about the C++ unit-testing framework Catch2. Catch uses another library, called Clara, for parsing command line arguments. Clara is an open-source, single-header, simple, composable and easy to use parser written by the author of Catch2. In this post, I will show how you can use Clara in C++ to parse command line arguments.<br \/>\n<!--more--><\/p>\n<p>Clara is available on Github at <a href=\"https:\/\/github.com\/catchorg\/Clara\">https:\/\/github.com\/catchorg\/Clara<\/a>. Although there is not much documentation at the moment, the library is easy to use. The following sample shows an example of using Clara. We&#8217;ll drill down on it in a moment. <\/p>\n<pre class=\"lang:c++ decode:true \" >#include &lt;iostream&gt;\r\n#include &lt;string&gt;\r\n\r\n#include \"clara.hpp\"\r\n\r\nenum class verbosity_level\r\n{\r\n   low, normal, debug\r\n};\r\n\r\nint main(int argc, char const * const * argv)\r\n{\r\n   using namespace clara;\r\n\r\n   auto source    = std::string{};\r\n   auto dest      = std::string{};\r\n   auto threshold = 0.0;\r\n   auto ignore    = false;\r\n   auto verbosity = verbosity_level::low;\r\n   auto depth     = 0;\r\n   auto showhelp  = false;\r\n\r\n   auto parser =\r\n      Opt(threshold, \"threshold\")[\"-t\"](\"Threshold for analysis inclusion\") |\r\n      Opt(ignore)[\"-i\"][\"--ignore\"](\"Ignore conflicts\") |\r\n      Opt(verbosity, \"low|normal|debug\")[\"-v\"][\"--verbosity\"](\"The verbosity level\") |\r\n      Opt([&amp;depth](int const d) \r\n      {\r\n         if (d &lt; 0 || d &gt; 10)\r\n         {\r\n            return ParserResult::runtimeError(\"Depth must be between 1 and 10\");\r\n         }\r\n         else\r\n         {\r\n            depth = d;\r\n            return ParserResult::ok(ParseResultType::Matched);\r\n         }\r\n      }, \"depth\")[\"-d\"](\"Depth of analysis (1 to 10)\") |\r\n      Arg(source, \"source\")(\"The path of the source\") |\r\n      Arg(dest, \"destination\")(\"The path to the result\") |\r\n      Help(showhelp);\r\n\r\n   try\r\n   {\r\n      auto result = parser.parse(Args(argc, argv));\r\n      if (!result)\r\n      {\r\n         std::cerr &lt;&lt; \"Error in command line: \" &lt;&lt; result.errorMessage() &lt;&lt; std::endl;\r\n         return 1;\r\n      }\r\n      else if (showhelp)\r\n      {\r\n         parser.writeToStream(std::cout);\r\n      }\r\n      else\r\n      {\r\n         std::cout &lt;&lt;\r\n            \"source:    \" &lt;&lt; source &lt;&lt; std::endl &lt;&lt;\r\n            \"dest:      \" &lt;&lt; dest &lt;&lt; std::endl &lt;&lt;\r\n            \"threshold: \" &lt;&lt; threshold &lt;&lt; std::endl &lt;&lt;\r\n            \"ignore:    \" &lt;&lt; ignore &lt;&lt; std::endl &lt;&lt;\r\n            \"verbosity: \" &lt;&lt; verbosity &lt;&lt; std::endl &lt;&lt;\r\n            \"dept:      \" &lt;&lt; depth &lt;&lt; std::endl;\r\n      }\r\n   }\r\n   catch (std::exception const &amp; e)\r\n   {\r\n      std::cout &lt;&lt; e.what() &lt;&lt; std::endl;\r\n   }\r\n\r\n   return 0;\r\n}<\/pre>\n<p>We can split this program into several parts:<\/p>\n<ul>\n<li>Declaration of variables to hold values of command line arguments.<\/li>\n<li>Creation of a parser by combining individual parsers <tt>clara::Opt<\/tt>, <tt>clara::Arg<\/tt>, and <tt>clara::Help<\/tt>.<\/li>\n<li>Parsing the command line with <tt>parse()<\/tt>.<\/li>\n<li>Interpreting the result and doing something based on the argument value. In this example, if the arguments were correctly parsed they are just printed to the console.<\/li>\n<\/ul>\n<p><tt>clara::Opt<\/tt> and <tt>clara::Arg<\/tt> are individiual parsers that are very similar execept for one important difference: the first specify an argument tied to an option (such as <tt>-v normal<\/tt> or <tt>--ignore<\/tt>) and the later to arguments that are not tied to an option (and therefore mising the square bracket names). Options are specified with <tt>-<\/tt> or <tt>--<\/tt> but on Windows <tt>\/<\/tt> is also accepted. <tt>clara::Help<\/tt> is yet another parser that always binds to a boolean variable setting it to <tt>true<\/tt> if any of the standard help options, <tt>-h<\/tt>, <tt>--help<\/tt> and <tt>-?<\/tt>, are found.<\/p>\n<p>To understand the <tt>Opt<\/tt> parser&#8217;s parts let&#8217;s take the following example:<\/p>\n<pre class=\"lang:c++ decode:true \" >Opt(threshold, \"threshold\")[\"-t\"](\"Threshold for analysis inclusion\")<\/pre>\n<p>There are three main parts in this construction:<\/p>\n<ul>\n<li><tt>(threshold, \"threshold\")<\/tt> specifies a variable (<tt>threshold<\/tt>) that will receive the value of the command line argument tied to the option and a hint (<tt>\"threshold\"<\/tt>) for the value.<\/tt>\n<li><tt>[\"-t\"]<\/tt> indicates one or more names for the option (for multiple names just chain them like <tt>[\"-t\"][\"-threshold\"]<\/tt>).<\/li>\n<li><tt>(\"Threshold for analysis inclusion\")<\/tt> indicates a description of the option.<\/li>\n<\/ul>\n<p>The syntax for <tt>Arg<\/tt> and <tt>Help<\/tt> is very similar, except that the square bracket names are missing. The description part is optional for all parser types.<\/p>\n<p>If you want to validate the input values for an option or argument, for instance to restrict a numeric value to a certain range, you can specify a lambda instead of the variable. This is shown in the previous example with the parsing of the <tt>depth<\/tt> option.<\/p>\n<pre class=\"lang:c++ decode:true \" >Opt([&amp;depth](int const d) \r\n{\r\n   if (d &lt; 0 || d &gt; 10)\r\n   {\r\n      return ParserResult::runtimeError(\"Depth must be between 1 and 10\");\r\n   }\r\n   else\r\n   {\r\n      depth = d;\r\n      return ParserResult::ok(ParseResultType::Matched);\r\n   }\r\n}, \"depth\")[\"-d\"](\"Depth of analysis (1 to 10)\")<\/pre>\n<p>Should the parsing be successful, you must return <tt>ParserResult::ok(ParseResultType::Matched)<\/tt>. Otherwise, you can return an error, such as <tt>ParserResult::runtimeError(\"Depth must be between 1 and 10\")<\/tt>.<\/p>\n<p>In the example above, <tt>verbosity<\/tt> is variable of type <tt>verbosity_level<\/tt>, which is a scoped enum. You can only bind to enums if have overwritten <tt>operator &gt;&gt;<\/tt> for them. Therefore, for my example to work, I have also implemented the following:<\/p>\n<pre class=\"lang:c++ decode:true \" >std::ostream&amp; operator &lt;&lt;(std::ostream&amp; stream, verbosity_level &amp; level)\r\n{\r\n   switch (level)\r\n   {\r\n   case verbosity_level::low:\r\n      stream &lt;&lt; \"low\";\r\n      break;\r\n   case verbosity_level::normal:\r\n      stream &lt;&lt; \"normal\";\r\n      break;\r\n   case verbosity_level::debug:\r\n      stream &lt;&lt; \"debug\";\r\n      break;\r\n   }\r\n   return stream;\r\n}\r\n\r\nstd::istream&amp; operator &gt;&gt;(std::istream&amp; stream, verbosity_level &amp; level)\r\n{\r\n   std::string token;\r\n   stream &gt;&gt; token;\r\n   if (token == \"low\") level = verbosity_level::low;\r\n   else if (token == \"normal\") level = verbosity_level::normal;\r\n   else if (token == \"debug\") level = verbosity_level::debug;\r\n   else {\r\n      auto parsed = false;\r\n      try {\r\n         auto n = std::stoi(token);\r\n         if (n &gt;= static_cast&lt;int&gt;(verbosity_level::low) &amp;&amp;\r\n             n &lt;= static_cast&lt;int&gt;(verbosity_level::debug))\r\n         {\r\n            level = static_cast&lt;verbosity_level&gt;(n);\r\n            parsed = true;\r\n         }\r\n      }\r\n      catch (std::exception const &amp;) { }\r\n\r\n      if(!parsed)\r\n         throw std::runtime_error(\"Invalid verbosity level value\");\r\n   }\r\n   \r\n   return stream;\r\n}<\/pre>\n<p>Parsing the actual command line options is done with a call to <tt>parse()<\/tt> and passing the arguments through an <tt>Args<\/tt> object. The result of the call is a <tt>clara::detail::InternalParseResult<\/tt> object. There are various ways to check its value. The explicit operator bool returns true if the type of the result is <tt>Ok<\/tt> (the other options being <tt>LogicError<\/tt> and <tt>RuntimeError<\/tt>).<\/p>\n<p>You can actually print the parser description to an output stream using the <tt>writeToStream()<\/tt> method. This is how the result looks for the example shown above:<\/p>\n<pre class=\"lang:default decode:true \" >clara_demo.exe \/?\r\nusage:\r\n  clara_demo.exe [&lt;source&gt; &lt;destination&gt;] options\r\n\r\nwhere options are:\r\n  -t &lt;threshold&gt;                        Threshold for analysis inclusion\r\n  -i, --ignore                          Ignore conflicts\r\n  -v, --verbosity &lt;low|normal|debug&gt;    The verbosity level\r\n  -d &lt;depth&gt;                            Depth of analysis (1 to 10)\r\n  -?, -h, --help                        display usage information<\/pre>\n<p>Let&#8217;s look at some parsing examples for the program above:<\/p>\n<ul>\n<li>no arguments provided\n<pre class=\"lang:default decode:true \" >\r\nclara_demo.exe\r\nsource:\r\ndest:\r\nthreshold: 0\r\nignore:    0\r\nverbosity: low\r\ndept:      0\r\n<\/pre>\n<\/li>\n<li>only one argument provided (i.e. <tt>source<\/tt>)\n<pre class=\"lang:default decode:true \" >\r\nclara_demo.exe c:\\temp\\input.dat\r\nsource:    c:\\temp\\input.dat\r\ndest:\r\nthreshold: 0\r\nignore:    0\r\nverbosity: low\r\ndept:      0\r\n<\/pre>\n<\/li>\n<li>both arguments provided (<tt>source<\/tt> and <tt>dest<\/tt>)\n<pre class=\"lang:default decode:true \" >\r\nclara_demo.exe c:\\temp\\input.dat c:\\temp\\output.txt\r\nsource:    c:\\temp\\input.dat\r\ndest:      c:\\temp\\output.txt\r\nthreshold: 0\r\nignore:    0\r\nverbosity: low\r\ndept:      0\r\n<\/pre>\n<\/li>\n<li>additionally option <tt>-t<\/tt> provided\n<pre class=\"lang:default decode:true \" >\r\nclara_demo.exe c:\\temp\\input.dat c:\\temp\\output.txt -t 3.14\r\nsource:    c:\\temp\\input.dat\r\ndest:      c:\\temp\\output.txt\r\nthreshold: 3.14\r\nignore:    0\r\nverbosity: low\r\ndept:      0\r\n<\/pre>\n<\/li>\n<li>additionally option <tt>-i<\/tt> or <tt>--ignore<\/tt> provided\n<pre class=\"lang:default decode:true \" >\r\nclara_demo.exe c:\\temp\\input.dat c:\\temp\\output.txt -t 3.14 -i\r\nsource:    c:\\temp\\input.dat\r\ndest:      c:\\temp\\output.txt\r\nthreshold: 3.14\r\nignore:    1\r\nverbosity: low\r\ndept:      0\r\n<\/pre>\n<\/li>\n<li>additionally option <tt>-d<\/tt> provided with valid numerical value in accepted range\n<pre class=\"lang:default decode:true \" >\r\nclara_demo.exe c:\\temp\\input.dat c:\\temp\\output.txt -t 3.14 -i -d 5\r\nsource:    c:\\temp\\input.dat\r\ndest:      c:\\temp\\output.txt\r\nthreshold: 3.14\r\nignore:    1\r\nverbosity: low\r\ndept:      5\r\n<\/pre>\n<\/li>\n<li>additionally option <tt>-d<\/tt> provided with invalid numerical value outside the accepted range\n<pre class=\"lang:default decode:true \" >\r\nclara_demo.exe c:\\temp\\input.dat c:\\temp\\output.txt -t 3.14 -i -d 55\r\nError in command line: Depth must be between 1 and 10\r\n<\/pre>\n<\/li>\n<li>additionally option <tt>-v<\/tt> provided with valid numerical value\n<pre class=\"lang:default decode:true \" >\r\nclara_demo.exe c:\\temp\\input.dat c:\\temp\\output.txt -t 3.14 -i -d 5 -v 1\r\nsource:    c:\\temp\\input.dat\r\ndest:      c:\\temp\\output.txt\r\nthreshold: 3.14\r\nignore:    1\r\nverbosity: normal\r\ndept:      5\r\n<\/pre>\n<\/li>\n<li>additionally option <tt>-v<\/tt> provided with valid textual value\n<pre class=\"lang:default decode:true \" >\r\nclara_demo.exe c:\\temp\\input.dat c:\\temp\\output.txt -t 3.14 -i -d 5 -v debug\r\nsource:    c:\\temp\\input.dat\r\ndest:      c:\\temp\\output.txt\r\nthreshold: 3.14\r\nignore:    1\r\nverbosity: debug\r\ndept:      5\r\n<\/pre>\n<\/li>\n<li>additionally option <tt>-v<\/tt> provided with invalid numerical value\n<pre class=\"lang:default decode:true \" >\r\nclara_demo.exe c:\\temp\\input.dat c:\\temp\\output.txt -t 3.14 -i -d 5 -v 10\r\nInvalid verbosity level value\r\n<\/pre>\n<\/li>\n<li>additionally option <tt>-v<\/tt> provided with invalid textual value\n<pre class=\"lang:default decode:true \" >\r\nclara_demo.exe c:\\temp\\input.dat c:\\temp\\output.txt -t 3.14 -i -d 5 -v high\r\nInvalid verbosity level value\r\n<\/pre>\n<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>In a <a href=\"http:\/\/mariusbancila.ro\/blog\/2018\/03\/29\/writing-cpp-unit-tests-with-catch2\/\">previous post<\/a>, I wrote about the C++ unit-testing framework Catch2. Catch uses another library, called Clara, for parsing command line arguments. Clara is an open-source, single-header, simple, composable and easy to use parser written by the author of Catch2. In this post, I will show how you can use Clara in C++ to parse command line arguments. <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_uag_custom_page_level_css":"","advgb_blocks_editor_width":"","advgb_blocks_columns_visual_guide":"","_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_feature_clip_id":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"jetpack_post_was_ever_published":false},"categories":[7],"tags":[451,548,491,138],"class_list":["post-2804","post","type-post","status-publish","format-standard","hentry","category-c","tag-c","tag-command-line","tag-github","tag-library"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.1.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"A look at the command line parser Clara, an open-source and easy to use library for C++.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Marius Bancila\"\/>\n\t<meta name=\"keywords\" content=\"c++,command line,github,library\" \/>\n\t<link rel=\"canonical\" href=\"https:\/\/mariusbancila.ro\/blog\/2018\/04\/03\/parsing-command-line-arguments-in-cpp-with-clara\/\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"en_US\" \/>\n\t\t<meta property=\"og:site_name\" content=\"Marius Bancila&#039;s Blog | About code. Mostly on C++\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"Parsing command line arguments in C++ with Clara\" \/>\n\t\t<meta property=\"og:description\" content=\"A look at the command line parser Clara, an open-source and easy to use library for C++.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/mariusbancila.ro\/blog\/2018\/04\/03\/parsing-command-line-arguments-in-cpp-with-clara\/\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2018-04-03T18:00:01+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2018-04-20T08:26:34+00:00\" \/>\n\t\t<meta name=\"twitter:card\" content=\"summary\" \/>\n\t\t<meta name=\"twitter:title\" content=\"Parsing command line arguments in C++ with Clara\" \/>\n\t\t<meta name=\"twitter:description\" content=\"A look at the command line parser Clara, an open-source and easy to use library for C++.\" \/>\n\t\t<script type=\"application\/ld+json\" class=\"aioseo-schema\">\n\t\t\t{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2018\\\/04\\\/03\\\/parsing-command-line-arguments-in-cpp-with-clara\\\/#article\",\"name\":\"Parsing command line arguments in C++ with Clara\",\"headline\":\"Parsing command line arguments in C++ with Clara\",\"author\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/#author\"},\"publisher\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#organization\"},\"datePublished\":\"2018-04-03T20:00:01+02:00\",\"dateModified\":\"2018-04-20T10:26:34+02:00\",\"inLanguage\":\"en-US\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2018\\\/04\\\/03\\\/parsing-command-line-arguments-in-cpp-with-clara\\\/#webpage\"},\"isPartOf\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2018\\\/04\\\/03\\\/parsing-command-line-arguments-in-cpp-with-clara\\\/#webpage\"},\"articleSection\":\"C++, C++, command line, github, library\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2018\\\/04\\\/03\\\/parsing-command-line-arguments-in-cpp-with-clara\\\/#breadcrumblist\",\"itemListElement\":[{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog#listItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/#listItem\",\"name\":\"IT\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/#listItem\",\"position\":2,\"name\":\"IT\",\"item\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/#listItem\",\"name\":\"Software\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog#listItem\",\"name\":\"Home\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/#listItem\",\"position\":3,\"name\":\"Software\",\"item\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/c\\\/#listItem\",\"name\":\"C++\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/#listItem\",\"name\":\"IT\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/c\\\/#listItem\",\"position\":4,\"name\":\"C++\",\"item\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/c\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2018\\\/04\\\/03\\\/parsing-command-line-arguments-in-cpp-with-clara\\\/#listItem\",\"name\":\"Parsing command line arguments in C++ with Clara\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/#listItem\",\"name\":\"Software\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2018\\\/04\\\/03\\\/parsing-command-line-arguments-in-cpp-with-clara\\\/#listItem\",\"position\":5,\"name\":\"Parsing command line arguments in C++ with Clara\",\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/c\\\/#listItem\",\"name\":\"C++\"}}]},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#organization\",\"name\":\"Marius Bancila's Blog\",\"description\":\"About code. Mostly on C++\",\"url\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/#author\",\"url\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/\",\"name\":\"Marius Bancila\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2018\\\/04\\\/03\\\/parsing-command-line-arguments-in-cpp-with-clara\\\/#authorImage\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/a84dd2831d955c38355ddea55df4df260809b88f36408bc14fd4eab8f7f131c9?s=96&d=mm&r=g\",\"width\":96,\"height\":96,\"caption\":\"Marius Bancila\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2018\\\/04\\\/03\\\/parsing-command-line-arguments-in-cpp-with-clara\\\/#webpage\",\"url\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2018\\\/04\\\/03\\\/parsing-command-line-arguments-in-cpp-with-clara\\\/\",\"name\":\"Parsing command line arguments in C++ with Clara\",\"description\":\"A look at the command line parser Clara, an open-source and easy to use library for C++.\",\"inLanguage\":\"en-US\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#website\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2018\\\/04\\\/03\\\/parsing-command-line-arguments-in-cpp-with-clara\\\/#breadcrumblist\"},\"author\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/#author\"},\"creator\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/#author\"},\"datePublished\":\"2018-04-03T20:00:01+02:00\",\"dateModified\":\"2018-04-20T10:26:34+02:00\"},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/\",\"name\":\"Marius Bancila's Blog\",\"description\":\"About code. Mostly on C++\",\"inLanguage\":\"en-US\",\"publisher\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#organization\"}}]}\n\t\t<\/script>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"Parsing command line arguments in C++ with Clara","description":"A look at the command line parser Clara, an open-source and easy to use library for C++.","canonical_url":"https:\/\/mariusbancila.ro\/blog\/2018\/04\/03\/parsing-command-line-arguments-in-cpp-with-clara\/","robots":"max-image-preview:large","keywords":"c++,command line,github,library","webmasterTools":{"miscellaneous":""},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/mariusbancila.ro\/blog\/2018\/04\/03\/parsing-command-line-arguments-in-cpp-with-clara\/#article","name":"Parsing command line arguments in C++ with Clara","headline":"Parsing command line arguments in C++ with Clara","author":{"@id":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/#author"},"publisher":{"@id":"https:\/\/mariusbancila.ro\/blog\/#organization"},"datePublished":"2018-04-03T20:00:01+02:00","dateModified":"2018-04-20T10:26:34+02:00","inLanguage":"en-US","mainEntityOfPage":{"@id":"https:\/\/mariusbancila.ro\/blog\/2018\/04\/03\/parsing-command-line-arguments-in-cpp-with-clara\/#webpage"},"isPartOf":{"@id":"https:\/\/mariusbancila.ro\/blog\/2018\/04\/03\/parsing-command-line-arguments-in-cpp-with-clara\/#webpage"},"articleSection":"C++, C++, command line, github, library"},{"@type":"BreadcrumbList","@id":"https:\/\/mariusbancila.ro\/blog\/2018\/04\/03\/parsing-command-line-arguments-in-cpp-with-clara\/#breadcrumblist","itemListElement":[{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog#listItem","position":1,"name":"Home","item":"https:\/\/mariusbancila.ro\/blog","nextItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/#listItem","name":"IT"}},{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/#listItem","position":2,"name":"IT","item":"https:\/\/mariusbancila.ro\/blog\/category\/it\/","nextItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/#listItem","name":"Software"},"previousItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog#listItem","name":"Home"}},{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/#listItem","position":3,"name":"Software","item":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/","nextItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/#listItem","name":"C++"},"previousItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/#listItem","name":"IT"}},{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/#listItem","position":4,"name":"C++","item":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/","nextItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/2018\/04\/03\/parsing-command-line-arguments-in-cpp-with-clara\/#listItem","name":"Parsing command line arguments in C++ with Clara"},"previousItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/#listItem","name":"Software"}},{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/2018\/04\/03\/parsing-command-line-arguments-in-cpp-with-clara\/#listItem","position":5,"name":"Parsing command line arguments in C++ with Clara","previousItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/#listItem","name":"C++"}}]},{"@type":"Organization","@id":"https:\/\/mariusbancila.ro\/blog\/#organization","name":"Marius Bancila's Blog","description":"About code. Mostly on C++","url":"https:\/\/mariusbancila.ro\/blog\/"},{"@type":"Person","@id":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/#author","url":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/","name":"Marius Bancila","image":{"@type":"ImageObject","@id":"https:\/\/mariusbancila.ro\/blog\/2018\/04\/03\/parsing-command-line-arguments-in-cpp-with-clara\/#authorImage","url":"https:\/\/secure.gravatar.com\/avatar\/a84dd2831d955c38355ddea55df4df260809b88f36408bc14fd4eab8f7f131c9?s=96&d=mm&r=g","width":96,"height":96,"caption":"Marius Bancila"}},{"@type":"WebPage","@id":"https:\/\/mariusbancila.ro\/blog\/2018\/04\/03\/parsing-command-line-arguments-in-cpp-with-clara\/#webpage","url":"https:\/\/mariusbancila.ro\/blog\/2018\/04\/03\/parsing-command-line-arguments-in-cpp-with-clara\/","name":"Parsing command line arguments in C++ with Clara","description":"A look at the command line parser Clara, an open-source and easy to use library for C++.","inLanguage":"en-US","isPartOf":{"@id":"https:\/\/mariusbancila.ro\/blog\/#website"},"breadcrumb":{"@id":"https:\/\/mariusbancila.ro\/blog\/2018\/04\/03\/parsing-command-line-arguments-in-cpp-with-clara\/#breadcrumblist"},"author":{"@id":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/#author"},"creator":{"@id":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/#author"},"datePublished":"2018-04-03T20:00:01+02:00","dateModified":"2018-04-20T10:26:34+02:00"},{"@type":"WebSite","@id":"https:\/\/mariusbancila.ro\/blog\/#website","url":"https:\/\/mariusbancila.ro\/blog\/","name":"Marius Bancila's Blog","description":"About code. Mostly on C++","inLanguage":"en-US","publisher":{"@id":"https:\/\/mariusbancila.ro\/blog\/#organization"}}]},"og:locale":"en_US","og:site_name":"Marius Bancila's Blog | About code. Mostly on C++","og:type":"article","og:title":"Parsing command line arguments in C++ with Clara","og:description":"A look at the command line parser Clara, an open-source and easy to use library for C++.","og:url":"https:\/\/mariusbancila.ro\/blog\/2018\/04\/03\/parsing-command-line-arguments-in-cpp-with-clara\/","article:published_time":"2018-04-03T18:00:01+00:00","article:modified_time":"2018-04-20T08:26:34+00:00","twitter:card":"summary","twitter:title":"Parsing command line arguments in C++ with Clara","twitter:description":"A look at the command line parser Clara, an open-source and easy to use library for C++."},"aioseo_meta_data":{"post_id":"2804","title":"Parsing command line arguments in C++ with Clara","description":"A look at the command line parser Clara, an open-source and easy to use library for C++.","keywords":[{"label":"C++","value":"C++"},{"label":"command line","value":"command line"},{"label":"github","value":"github"},{"label":"library","value":"library"}],"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"location":null,"local_seo":null,"breadcrumb_settings":null,"limit_modified_date":false,"ai":null,"created":"2021-03-18 21:04:51","updated":"2025-12-12 07:48:31","seo_analyzer_scan_date":null,"focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"author_meta":{"display_name":"Marius Bancila","author_link":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/"},"featured_img":null,"jetpack_publicize_connections":[],"uagb_featured_image_src":{"full":false,"thumbnail":false,"medium":false,"medium_large":false,"large":false,"1536x1536":false,"2048x2048":false},"uagb_author_info":{"display_name":"Marius Bancila","author_link":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/"},"uagb_comment_info":0,"uagb_excerpt":"In a previous post, I wrote about the C++ unit-testing framework Catch2. Catch uses another library, called Clara, for parsing command line arguments. Clara is an open-source, single-header, simple, composable and easy to use parser written by the author of Catch2. In this post, I will show how you can use Clara in C++ to&hellip;","coauthors":[],"tax_additional":{"categories":{"linked":["<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/\" class=\"advgb-post-tax-term\">C++<\/a>"],"unlinked":["<span class=\"advgb-post-tax-term\">C++<\/span>"]},"tags":{"linked":["<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/\" class=\"advgb-post-tax-term\">C++<\/a>","<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/\" class=\"advgb-post-tax-term\">command line<\/a>","<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/\" class=\"advgb-post-tax-term\">github<\/a>","<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/\" class=\"advgb-post-tax-term\">library<\/a>"],"unlinked":["<span class=\"advgb-post-tax-term\">C++<\/span>","<span class=\"advgb-post-tax-term\">command line<\/span>","<span class=\"advgb-post-tax-term\">github<\/span>","<span class=\"advgb-post-tax-term\">library<\/span>"]}},"comment_count":"0","relative_dates":{"created":"Posted 9 years ago","modified":"Updated 8 years ago"},"absolute_dates":{"created":"Posted on April 3, 2018","modified":"Updated on April 20, 2018"},"absolute_dates_time":{"created":"Posted on April 3, 2018 8:00 pm","modified":"Updated on April 20, 2018 10:26 am"},"featured_img_caption":"","series_order":"","jetpack_shortlink":"https:\/\/wp.me\/pYNdv-Je","jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/posts\/2804","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/comments?post=2804"}],"version-history":[{"count":18,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/posts\/2804\/revisions"}],"predecessor-version":[{"id":2904,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/posts\/2804\/revisions\/2904"}],"wp:attachment":[{"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/media?parent=2804"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/categories?post=2804"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/tags?post=2804"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}