Taywee /
args
A simple header-only C++ argument parser library. Supposed to be flexible and powerful, and attempts to be compatible with the functionality of the Python standard argparse library (though not necessarily the API).
Loading repository data…
morrisfranken / repository
A Simple Argument Parser for C++
A lightweight header-only library for parsing command line arguments in an elegant manner. Argparse allows you to define variables as a one-liner without redefining their type or names while representing all the program arguments in a struct that can be easily passed to functions.
#include "argparse/argparse.hpp"
struct MyArgs : public argparse::Args {
std::string &anonymous = arg("an anonymous positional string argument");
std::string &src_path = arg("src_path", "a positional string argument");
int &k = kwarg("k", "A keyworded integer value");
float &alpha = kwarg("a,alpha", "An optional float value").set_default(0.5f);
bool &verbose = flag("v,verbose", "A flag to toggle verbose");
};
int main(int argc, char* argv[]) {
auto args = argparse::parse<MyArgs>(argc, argv);
if (args.verbose)
args.print(); // prints all variables
return 0;
}
Example output when setting the verbose flag in the example above, it will print the capturing arguments with the args.print() function:
$ ./argparse_test hello source -k 4 --verbose
arg_0(an anon...) : hello
src_path(a posit...) : source
-k : 4
-a,--alpha : 0.5
-v,--verbose : true
-?,--help : false
Argparse distinguishes 3 different types of arguments:
| Type | Function |
|---|---|
arg(help) | anonymous positional arguments |
arg(key,help) | named positional arguments |
kwarg(key,help,implicit) | keyworded-arguments that require a key and a value, e.g. --variable 0.5. |
flag(key,help) | a boolean argument that is by default false, but can be set to true by defining it on the commandline (e.g. --verbose) |
Argparse supports the following syntax:
--long
--long=value
--long value
-a
-ab
-abc=value
-abc value
Where on the last 2 lines, a and b are considered flags, while c is considered a kwarg and is set to value. In addition, an argument may be a comma-separated vector.
Args and Kwargs may have a default value, which will be used when the argument is not present on the commandline. These can be passed through the set_default function, it accepts either a string or the type of the parameter itself:
std::string &dst_path = arg("An optional positional argument").set_default("output.png");
float &alpha = kwarg("a,alpha", "An optional float parameter with float as default").set_default(0.5f);
float &beta = kwarg("b,beta", "An optional float parameter with string as default").set_default("0.5");
std::vector<int> &numbers = kwarg("n,numbers", "An optional vector of integers").set_default(std::vector<int>{1,2});
std::vector<int> &values = kwarg("v,values", "An optional vector of integers, with string as default").set_default("3,4");
Kwargs may have an implicit value, meaning that when the argument is present on the commandline, but no value is set, it will use the implicit value. Implicit values are passed as string.
int &k = kwarg("k", "An implicit int parameter", /*implicit*/"3");
float &alpha = kwarg("a,alpha", "A implicit float parameter", /*implicit*/"0.5");
std::vector<int> &numbers = kwarg("n,numbers", "A implicit int vector", /*implicit*/"1,2,3");
Examples:
On the commandline the implicit values can be overwritten by using the = sign followed by the value. Examples:
$ argparse_test -k
k = 3
$ argparse_test -k=9
k = 9
$ argparse_test --numbers
numbers = 1,2,3
$ argparse_test --numbers=3,4,5
numbers = 3,4,5
Argparse supports std::vector. There are 2 ways in which the vector can be read from the commandline, either a vector can be parsed from a comma-separated string, or by setting the multi_argument() flag to aggregate multiple program arguments into the vector, e.g. when using the ./* in bash to list all the files in a directory.
std::vector<int> &numbers = kwarg("n,numbers", "An int vector");
std::vector<std::string> &tags = kwarg("t,tags", "A word vector");
std::vector<std::string> &files = kwarg("files", "multiple arguments").multi_argument();
Example usage:
$ argparse_test --numbers 3,4,5,6
$ argparse_test --numbers=3,4,5,6
$ argparse_test --tags hello
$ argparse_test --tags="1st tag,2nd tag" # if the strings contain spaces
$ argparse_test --files a b c
$ argparse_test --files ./* # files will now contain a list of the files in the current directory
In case there are other positional arguments, Argparse will make sure that they are correctly assigned. For example, consider the following example:
std::string &A = arg("Source path");
std::vector<std::string> &B = arg("Variable paths").multi_argument();
std::string &C = arg("Last");
And the following input:
$ argparse_test a b b b c
Argparse will assign the non-multiple arguments first, such that A=a, C=c and B=b,b,b
In situations where setting a default value is not sufficient, Argparse supports std::optional, and (smart)pointers, these can be used in situations where you'd like to distinguish whether an argument was set by the user. When declaring a raw pointer or a std::shared_ptr, the default value for these are automatically set to nullptr (or std::nullopt for std::optional).
std::shared_ptr<float> &alpha = kwarg("a,alpha", "An optional smart-pointer float parameter");
std::optional<float> &beta = kwarg("b,beta", "An optional float parameter with std::optional return");
float* &gamma = kwarg("g,gamma", "An optional raw pointer float parameter");
For example:
$ ./argparse_test --alpha 0.4
-a,--alpha : 0.4
-b,--beta : none
-g,--gamma : none
One of the reasons for creating this library was to natively support Enums using magic_enum. If it is found on the system, Argparse supports automatic conversion from commandline to enum. Consider the following example:
enum Color {
RED,
BLUE,
GREEN,
};
struct MyArgs : public argparse::Args {
Color &color = kwarg("c,color", "An Enum input");
};
int main(int argc, char* argv[]) {
auto args = argparse::parse<MyArgs>(argc, argv);
args.print(); // prints all variables
return 0;
}
Running it will automatically convert the input to the Color enum (case-insensitive):
$ ./argparse_test --color blue
It will only accept a is_valid input for enums, and the help-tip will display the available options for this enum:
$ ./argparse_test --help
...
-c,--color : An Enum input [allowed: <red, blue, green>, required]
...
Argparse supports subcommands by creating a separate argparse::Args instance for them. Argparse currently supports 2 ways of defining the logic for subcommands:
int run() function within the Subcommand struct that will be executed once the user requests the specified subcommand.To add the subcommand to your program, add a line to your main program arguments specifying the class and the name of the subcommand using the subcommand function as shown below (using the int run() method):
struct CommitArgs : public argparse::Args {
bool &all = flag("a,all", "Tell the command to automatically stage files that have been modified and deleted, but new files you have not told git about are not affected.");
std::string &message = kwarg("m,message", "Use the given <msg> as the commit message.");
// This will be executed via `args.run_subcommands()` if the user calls the `commit` subcommand
int run() override {
std::cout << "running commit with the with the following message: " << this->message << std::endl;
return 0;
}
};
struct PushArgs : public argparse::Args {
std::string &source = arg("Source repository").set_default("origin");
std::string &destination = arg("Destination repository").set_default("master");
void welcome() override {
std::cout << "Push code changes to remote" << std::endl;
}
// This will be executed via `args.run_subcommands()` if the user calls the `push` subcommand
int run() override {
std::cout << "running push with the following parameters" << std::endl;
print();
return 0;
}
};
struct MyArgs : public argparse::Args {
bool &version = flag("v,version", "Print version");
CommitArgs &commit = subcommand("commit");
PushArgs &push = subcommand("push");
};
int main(int argc, char* argv[]) {
auto args = argparse::parse<MyArgs>(argc, argv);
if (args.version) {
std::cout << "argparse_subcomands version 1.0.0" << std::endl;
return 0;
}
return args.run_subcommands();
}
Alternatively, you can define the logic for the subcommand within the main function as shown below without having to define the int run() method in the subcommand struct
//
int main(int argc, char* argv[]) {
auto args = argparse::parse<MyArgs>(argc, argv);
if (args.commit.is_valid) {
std::cout << "running commit with the with the following message: " << args.commit.message << std::endl;
} else if (args.push.is_valid) {
std::cout << "running push with the following parameters" << std::endl;
args.push.print();
} else {
std::cout << "No subcommand given" << std::endl;
}
return 0
}
Usage of the above example:
$ ./argparse_subcommands commit -am "hello world"
running commit with the with the following message: hello world
$ ./argparse_subcommands push origin dev
running push with the following parameters
arg_0(Source ...) : origin
arg_1(Destina...) : dev
--help : false
$ ./argparse_subcommands commit --help
Usage: commit [options...]
Options:
-a,--all : Tell the command to automatically stage files that have been modified and deleted, but new files you have not told git about are not affected. [implicit: "true", default: false]
-m,--message : Use the given <msg> as the commit message. [required]
--help : print help [implicit: "true", default: false]
When using a custom class, Argparse will try to create the class using the constructor with an std::string as parameter. See examples/argparse_example.cpp for an example using a custom class.
When invalid arguments are passed to the commandline, argparse will simply print the error and exit the program by default. However, you can choose to let argparse throw a catchable exception instead by setting the raise_on_error flag to true on the parse function. For example:
int main(int argc, char* argv[]) {
try {
auto args = argparse::parse<MyArgs>(argc, argv, /*raise_on_error*/ true);
} catch (const std::runtime_error &e) {
std::cerr << "failed to parse argume
Selected from shared topics, language and repository description—not editorial ratings.
Taywee /
A simple header-only C++ argument parser library. Supposed to be flexible and powerful, and attempts to be compatible with the functionality of the Python standard argparse library (though not necessarily the API).
gouwsxander /
A simple, single-header argument parser for C
vietjtnguyen /
A simple C++11 command line argument parser
jamolnng /
A simple C++ header only command line argument parser
pfultz2 /
Simple and type-safe commandline argument parser for C++14
sanusanth /
What is JavaScript and what does it do? Before you start learning something new, it’s important to understand exactly what it is and what it does. This is especially useful when it comes to mastering a new programming language. In simple terms, JavaScript is a programming language used to make websites interactive. If you think about the basic makeup of a website, you have HTML, which describes and defines the basic content and structure of the website, then you have CSS, which tells the browser how this HTML content should be displayed—determining things like color and font. With just HTML and CSS, you have a website that looks good but doesn’t actually do much. JavaScript brings the website to life by adding functionality. JavaScript is responsible for elements that the user can interact with, such as drop-down menus, modal windows, and contact forms. It is also used to create things like animations, video players, and interactive maps. Nowadays, JavaScript is an all-purpose programming language—meaning it runs across the entire software stack. The most popular application of JavaScript is on the client side (aka frontend), but since Node.js came on the scene, many people run JavaScript on the server side (aka backend) as well. When used on the client side, JavaScript code is read, interpreted, and executed in the user’s web browser. When used on the server side, it is run on a remote computer. You can learn more about the difference between frontend and backend programming here. JavaScript isn’t only used to create websites. It can also be used to build browser-based games and, with the help of certain frameworks, mobile apps for different operating systems. The creation of new libraries and frameworks is also making it possible to build backend programs with JavaScript, such as web apps and server apps. Is it still worth learning JavaScript in 2021? The world of web development is constantly moving. With so many new tools popping up all the time, it can be extremely difficult to know where you should focus your efforts. As an aspiring developer, you’ll want to make sure that what you’re learning is still relevant in today’s industry. If you’re having doubts about JavaScript, it’s important to know that, since its creation in 1995, JavaScript is pretty much everywhere on the web—and that’s not likely to change any time soon. According to the 2020 StackOverflow developer survey, JavaScript is the most commonly used programming language for the eighth year in a row. It is currently used by 94.5% of all websites and, despite originally being designed as a client-side language, JavaScript has now made its way to the server-side of websites (thanks to Node.js), mobile devices (thanks to React Native and Ionic) and desktop (courtesy of Electron). As long as people are interacting with the web, you can assume that JavaScript is highly relevant—there’s no doubt that this is a language worth knowing! With that in mind, let’s look at some of the key benefits of becoming a JavaScript expert. Why learn JavaScript? The most obvious reason for learning JavaScript is if you have hopes of becoming a web developer. Even if you haven’t got your heart set on a tech career, being proficient in JavaScript will enable you to build websites from scratch—a pretty useful skill to have in today’s job market! If you do want to become a web developer, here are some of the main reasons why you should learn JavaScript: JavaScript experts are versatile JavaScript is an extremely versatile language. Once you’ve mastered it, the possibilities are endless: you can code on the client-side (frontend) using Angular and on the server-side (backend) using Node.js. You can also develop web, mobile, and desktop apps using React, React Native, and Electron, and you can even get involved in machine learning. If you want to become a frontend developer, JavaScript is a prerequisite. However, that’s not the only career path open to you as a JavaScript expert. Mastering this key programming language could see you go on to work in full-stack development, games development, information security software engineering, machine learning, and artificial intelligence—to name just a few! Ultimately, if you want any kind of development or engineering career, proficiency in JavaScript is a must. JavaScript experts are in-demand (and well-paid) JavaScript is the most popular programming language in the world, so it’s no wonder that JavaScript is one of the most sought-after skills in the web development industry today. According to the Devskiller IT Skills and Hiring Report 2020, 72% of companies are looking to hire JavaScript experts. Enter the search term “JavaScript” on job site Indeed and you’ll find over 40,000 jobs requiring this skill (in the US). Run the same search on LinkedIn and the results are in excess of 125,000. At the same time, the global demand for JavaScript seems to outweigh the expertise available on the market. According to this 2018 HackerRank report, 48% of employers worldwide need developers with JavaScript skills, while only 42% of student developers claim to be proficient in JavaScript. And, in their most recent report for 2020, HackerRank once again reports that JavaScript is the most popular language that hiring mangers look for in a web developer candidate. Not only are JavaScript experts in demand—they are also well-paid. In the United States, JavaScript developers earn an average yearly salary of $111,953 per year. We’ve covered this topic in more detail in our JavaScript salary guide, but as you can see, learning JavaScript can really boost your earning potential as a developer. JavaScript is beginner-friendly Compared to many other programming languages, JavaScript offers one of the more beginner-friendly entry points into the world of coding. The great thing about JavaScript is that it comes installed on every modern web browser—there’s no need to set up any kind of development environment, which means you can start coding with JavaScript right away! Another advantage of learning JavaScript as your first programming language is that you get instant feedback; with a minimal amount of JavaScript code, you’ll immediately see visible results. There’s also a huge JavaScript community on sites like Stack Overflow, so you’ll find plenty of support as you learn. Not only is JavaScript beginner-friendly; it will also set you up with some extremely valuable transferable skills. JavaScript supports object-oriented, functional, and imperative styles of programming—skills which can be transferred to any new language you might learn later on, such as Python, Java, or C++. JavaScript provides a crucial introduction to key principles and practices that you’ll take with you throughout your career as a developer. Should you learn plain JavaScript first or can you skip to frameworks and libraries? When deciding whether or not to learn JavaScript, what you’re really asking is whether or not you should learn “vanilla” JavaScript. Vanilla JavaScript just means plain JavaScript without any libraries or frameworks. Let’s explore what this means in more detail now. What is meant by vanilla JavaScript, libraries, and frameworks? If you research the term “vanilla JavaScript”, you might run into some confusion; however, all you need to know is that vanilla JavaScript is used to refer to native, standards-based, non-extended JavaScript. There is no difference between vanilla JavaScript and JavaScript—it’s just there to emphasize the usage of plain JavaScript without the use of libraries and frameworks. So what are libraries and frameworks? JavaScript libraries and frameworks both contain sets of prewritten, ready-to-use JavaScript code—but they’re not the same thing. You can think of a framework as your blueprint for building a website: it gives you a structure to work from, and contains ready-made components and tools that help you to build certain elements much quicker than if you were to code them from scratch. Some popular JavaScript frameworks include Angular, React, Vue, and Node.js. Frameworks also contain libraries. Libraries are smaller than frameworks, and tend to be used for more specific cases. A JavaScript library contains sets of JavaScript code which can be called upon to implement certain functions and features. Let’s imagine you want to code a particular element into your website. You could write, say, ten lines of JavaScript from scratch—or you could take the condensed, ready-made version from your chosen JavaScript library. Some examples of JavaScript libraries include jQuery, Lodash, and Underscore. The easiest way to understand how frameworks and libraries work together is to imagine you are building a house. The framework provides the foundation and the structure, while the library enables you to add in ready-made components (like furniture) rather than building your own from scratch. You can learn more about the relationship between languages and libraries in this post explaining the main differences between JavaScript and jQuery. For now, let’s go back to our original question: How important is it to learn vanilla JavaScript? Should you learn vanilla JavaScript first? When it comes to learning JavaScript, it can be tempting to skip ahead to those time-saving frameworks and libraries we just talked about—and many developers do. However, there are many compelling arguments for learning plain JavaScript first. While JavaScript frameworks may help you get the job done quicker, there’s only so far you can go if you don’t understand the core concepts behind these frameworks. Frontend developer Abhishek Nagekar describes how not learning vanilla JavaScript came back to bite him when he started learning the JavaScript frameworks Node and Express: “As I went to write more and more code in Node and Express, I began to get stuck at even the tiniest problems. Suddenly, I was surrounded with words like callbacks, closures, event loop and prototype. It felt like I got a reintroduction to JavaScript, but this time, it was not a toddler playing in its cradle, it was something of a mysterious monster, challenging me on every other step for not having taken it seriously.” The above Tweet references a long-running joke within the developer community, and although it dates way back to 2015, it’s still highly relevant today. If you want to become a developer who can innovate, not just execute, you need to understand the underlying principles of the web—not just the shortcuts. This means learning vanilla JavaScript before you move on to frameworks. In fact, understanding plain JavaScript will help you later on when it comes to deciding whether to use a framework for a certain project, and if so, which framework to use. Why Study JavaScript? JavaScript is one of the 3 languages all web developers must learn: 1. HTML to define the content of web pages 2. CSS to specify the layout of web pages 3. JavaScript to program the behavior of web pages Learning Speed In this tutorial, the learning speed is your choice. Everything is up to you. If you are struggling, take a break, or re-read the material. Always make sure you understand all the "Try-it-Yourself" examples. The only way to become a clever programmer is to: Practice. Practice. Practice. Code. Code. Code ! Commonly Asked Questions How do I get JavaScript? Where can I download JavaScript? Is JavaScript Free? You don't have to get or download JavaScript. JavaScript is already running in your browser on your computer, on your tablet, and on your smart-phone. JavaScript is free to use for everyone.