cpp_n00b cpp_n00b - 25 days ago 8
C++ Question

Design pattern for accepting stdin OR CLI arguments

For C++, how do I accept CLI arguments or stdin?

For instance, let's say I have a function

foo()
that I want to call over a variable number of arguments. For standard args, I simply use something like:

int main(int argc, char* argv[]) {
if (argc < 2) {
std::cout << "usage goes here.\n";
} else {
for (int i; i < argc; ++i) {
foo(argv[i]);
}
}
}


But what if they sent them to me via stdin and piped the parameters to my application? Is there a way to detect and accept/handle both? What is an efficient design pattern to do this in modern C++ (C++11 and beyond)?

I'm interested in the design pattern / sample implementation. Feel free to reference a library that does this (Boost?) but please share/explain an example implementation.

Answer Source

Normally you would only read input from stdin, not arguments/options. By reading and evaluating arguments/options, the program should decide if it expects input from stdin or e.g. a file argument.

As example from the manpage of grep:

Synopsis

grep [OPTIONS] PATTERN [FILE...]

Description

grep searches the named input FILEs (or standard input if no files are named, or if a single hyphen-minus (-) is given as file name) for lines containing a match to the given PATTERN.

A lack of the FILE argument or the - option indicates grep to read stdin.

Invokation of your program could look like this, the lack of the file argument indicates reading input from stdin:

# file argument, input is in the file
command -o someoption filename

# file content supplied via stdin
command -o someoption < filename     

# with pipe and - (stdin) as file argument
othercommand | command -o someoption -

For parsing options/arguments boost has the program options library