C Programming Command Line
Essential Concepts

C Command Line Arguments - Complete Guide

Master command line arguments in C with detailed explanations of argc and argv, practical examples for parsing inputs, and best practices for building robust CLI applications.

argc & argv

Core parameters

CLI Applications

Real-world usage

Argument Parsing

Advanced techniques

Introduction to Command Line Arguments

Command line arguments allow users to pass information to a C program when it starts executing. This makes programs more flexible, configurable, and suitable for automation and scripting.

Why Use Command Line Arguments?
  • Flexibility: Configure program behavior without recompiling
  • Automation: Script and automate program execution
  • User-Friendly: Provide intuitive interface for power users
  • Batch Processing: Process multiple files or datasets
  • Portability: Standard across all operating systems
Common Use Cases
  • File Processing: Pass input/output filenames
  • Configuration: Set program options and flags
  • Data Input: Provide numerical parameters
  • Mode Selection: Choose between operation modes
  • Debugging: Enable verbose output or debugging

Key Components

The main() function in C can accept two parameters: argc (argument count) and argv (argument vector). These parameters give your program access to command line inputs, making it interactive and configurable.

argc and argv Parameters

The argc (argument count) and argv (argument vector) are the two parameters that enable command line argument processing in C programs.

Standard main() Function Signature:
int main(int argc, char *argv[]) { // Program code here return 0; }

Parameter Details:

Parameter Type Description Example Value
argc int Argument count - number of command line arguments For command: program arg1 arg2, argc = 3
argv char *[] Argument vector - array of strings containing arguments argv[0] = "program", argv[1] = "arg1", argv[2] = "arg2"

Memory Layout Visualization:

argv[0]
"program.exe"
argv[1]
"input.txt"
argv[2]
"output.txt"
argv[3]
NULL
argc = 3 | argv[argc] = NULL
Basic Example: Printing All Arguments
#include <stdio.h>

int main(int argc, char *argv[]) {
    int i;
    printf("argc = %d\n", argc);
    for (i = 0; i < argc; i++)
        printf("argv[%d] = %s\n", i, argv[i]);
    return 0;
}
$
./myprogram file1.txt file2.txt -v

Output:
Total arguments: 4
Program name: ./myprogram

All arguments:
argv[0] = ./myprogram
argv[1] = file1.txt
argv[2] = file2.txt
argv[3] = -v

Arguments (excluding program name):
Argument 1: file1.txt
Argument 2: file2.txt
Argument 3: -v

Parsing Command Line Arguments

Proper parsing of command line arguments involves validation, type conversion, and handling different argument formats like flags, options, and values.

Example 1: Basic Argument Validation
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
    if (argc != 2) {
        printf("Usage: %s <number>\n", argv[0]);
        return 1;
    }
    printf("You entered: %s\n", argv[1]);
    return 0;
}
Example 2: File Processing with Arguments
#include <stdio.h>

int main(int argc, char *argv[]) {
    if (argc < 2) {
        printf("Usage: %s <filename>\n", argv[0]);
        return 1;
    }
    printf("Would process: %s\n", argv[1]);
    return 0;
}
Example 3: Handling Flags and Options
#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[]) {
    int verbose = 0, i;
    for (i = 1; i < argc; i++)
        if (strcmp(argv[i], "-v") == 0) verbose = 1;
    printf("verbose = %d\n", verbose);
    return 0;
}

Advanced Argument Processing

Advanced techniques include using getopt() for standard argument parsing, handling multiple argument types, and creating robust CLI applications.

Using getopt() for Standard Argument Parsing
#include <stdio.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
    int opt;
    while ((opt = getopt(argc, argv, "hv")) != -1) {
        if (opt == 'h') { printf("Help\n"); return 0; }
        if (opt == 'v') printf("Verbose on\n");
    }
    return 0;
}
Advanced: Argument Parsing with Structures
#include <stdio.h>

typedef struct { int help; int verbose; } Options;

int main(int argc, char *argv[]) {
    Options o = {0, 0};
    (void)argc; (void)argv;
    printf("options struct ready\n");
    return 0;
}

Practical Applications

Command line arguments are used in various real-world applications. Here are practical examples demonstrating their utility.

Example: Calculator with Command Line Interface
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
    if (argc != 4) {
        printf("Usage: %s <a> <op> <b>\n", argv[0]);
        return 1;
    }
    int a = atoi(argv[1]), b = atoi(argv[3]);
    char op = argv[2][0];
    if (op == '+') printf("%d\n", a + b);
    else printf("unsupported op\n");
    return 0;
}
$
./calculator add 12.5 7.3
./calculator pow 2 10
./calculator sin 1.57

Output:
12.50 + 7.30 = 19.80
2.00 ^ 10.00 = 1024.00
sin(1.57) = 1.0000

Common Mistakes and Best Practices

Common Mistake 1: Not checking argc before accessing argv
// DANGEROUS: May cause segmentation fault printf("First argument: %s\n", argv[1]);
// SAFE: Always check argc first if(argc > 1) { printf("First argument: %s\n", argv[1]); }
Common Mistake 2: Not validating argument types
// RISKY: atoi() returns 0 for invalid input int value = atoi(argv[1]);
// BETTER: Use strtol() with error checking char *endptr; long value = strtol(argv[1], &endptr, 10); if(*endptr != '\0') { fprintf(stderr, "Error: Invalid number '%s'\n", argv[1]); return 1; }
Common Mistake 3: Not handling missing required arguments
// POOR: Assumes arguments exist FILE *fp = fopen(argv[1], "r");
// GOOD: Validate and provide helpful error if(argc < 2) { fprintf(stderr, "Error: Input filename required\n"); fprintf(stderr, "Usage: %s <filename>\n", argv[0]); return 1; }
Command Line Argument Best Practices:
  1. Always validate argc: Check argument count before accessing argv elements
  2. Provide helpful error messages: Include usage instructions in error output
  3. Use standard conventions: Follow POSIX/GNU conventions for option naming
  4. Implement -h/--help: Always include a help option that explains usage
  5. Validate input types: Check that arguments are valid numbers, files exist, etc.
  6. Use meaningful names: Choose option names that clearly indicate their purpose
  7. Support both short and long options: Allow -v and --verbose for user convenience
  8. Return proper exit codes: Use different return values for different error conditions
  9. Document thoroughly: Provide clear documentation for all options
  10. Test edge cases: Test with no arguments, invalid arguments, and boundary cases

Key Takeaways

  • Command line arguments are passed to main() via argc (count) and argv (array of strings)
  • argv[0] always contains the program name, argv[argc] is always NULL
  • Always validate argc before accessing argv elements to avoid segmentation faults
  • Use atoi(), atof(), or strtol() to convert string arguments to numbers
  • Implement -h or --help options to display usage instructions
  • Follow standard conventions: single-letter options (-v) and long options (--verbose)
  • Use getopt() (POSIX) or getopt_long() (GNU) for robust option parsing
  • Return meaningful exit codes: 0 for success, non-zero for errors
  • Provide clear error messages that guide users toward correct usage
  • Test your program with various argument combinations, including edge cases
Next Topics: We'll explore preprocessor directives and importance.