command-line-arguments
user-input
programming
software-development
cplusplus

User input and command line arguments

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Command-line programs usually get data in two ways: arguments supplied when the program starts and input entered while the program is running. Both are useful, but they serve different roles and lead to different program designs.

Command-line arguments

Command-line arguments are passed by the operating system when the process starts. In C and C++, they are exposed through argc and argv in main.

cpp
1#include <iostream>
2
3int main(int argc, char* argv[]) {
4    std::cout << "Program name: " << argv[0] << '\n';
5
6    for (int i = 1; i < argc; ++i) {
7        std::cout << "Argument " << i << ": " << argv[i] << '\n';
8    }
9}

A typical use case is non-interactive configuration. For example, a backup tool may accept a source path, a destination path, and flags such as --verbose or --dry-run. This makes the program easy to automate from scripts, schedulers, and CI jobs.

Arguments are best when the input is known before execution. They also make command history and reproducibility easier because the exact invocation can be logged or rerun.

Interactive user input

User input is collected after the program starts, usually through standard input. In C++, this often means std::cin or std::getline.

cpp
1#include <iostream>
2#include <string>
3
4int main() {
5    std::string name;
6    std::cout << "Enter your name: ";
7    std::getline(std::cin, name);
8
9    std::cout << "Hello, " << name << "!\n";
10}

Interactive input is appropriate when the program needs a conversation with the user. Setup wizards, confirmation prompts, shells, and menu-based tools all rely on this style.

The tradeoff is that interactive programs are harder to automate. A script can pass arguments easily, but feeding prompts and reading replies is more fragile.

Combining both approaches

Many well-designed CLI tools use both. Arguments define mode and defaults, while interactive input fills in missing information.

cpp
1#include <iostream>
2#include <string>
3
4int main(int argc, char* argv[]) {
5    std::string filename;
6
7    if (argc > 1) {
8        filename = argv[1];
9    } else {
10        std::cout << "Enter a file name: ";
11        std::getline(std::cin, filename);
12    }
13
14    std::cout << "Processing: " << filename << '\n';
15}

This pattern makes the program convenient for both humans and automation. A user can run it without memorizing every flag, while a script can pass all required values up front.

Parsing and validation matter

Raw access to argv works for simple tools, but larger programs benefit from a parser library or a disciplined parsing layer. Even without a library, you should validate counts, ranges, and required values.

cpp
1#include <iostream>
2#include <stdexcept>
3#include <string>
4
5int parse_port(const std::string& text) {
6    int port = std::stoi(text);
7    if (port < 1 || port > 65535) {
8        throw std::out_of_range("port out of range");
9    }
10    return port;
11}
12
13int main(int argc, char* argv[]) {
14    if (argc != 2) {
15        std::cerr << "Usage: server PORT\n";
16        return 1;
17    }
18
19    try {
20        int port = parse_port(argv[1]);
21        std::cout << "Starting on port " << port << '\n';
22    } catch (const std::exception& ex) {
23        std::cerr << "Invalid port: " << ex.what() << '\n';
24        return 1;
25    }
26}

The same principle applies to interactive input. Never assume the user typed a valid number, date, or path.

Choosing the right interface

Use arguments when repeatability, scripting, or non-interactive execution matters. Use prompts when the program needs live decisions, hidden input, or a guided workflow.

A good rule is this: if another program may call your tool, prefer arguments first. If a human is the only caller and the workflow is exploratory, interactive input can be the better experience.

Common Pitfalls

One common bug comes from mixing operator>> with std::getline without consuming the leftover newline. After a numeric extraction, the next getline may appear to skip input unless you clear the pending newline.

Another issue is forcing interactive prompts in tools that should work in automation. CI jobs, cron tasks, and container entrypoints can hang forever if the program unexpectedly waits on standard input.

A third mistake is not validating input. Whether data comes from argv or from the keyboard, it can still be missing, malformed, or hostile.

Summary

  • Command-line arguments are passed at startup and are ideal for automation and reproducibility.
  • Interactive input is collected during execution and works well for guided user workflows.
  • Many programs combine both by taking arguments first and prompting only when needed.
  • Always validate values from both sources before using them.
  • Be careful when mixing formatted extraction with std::getline in C++.

Course illustration
Course illustration

All Rights Reserved.