c
examples
examples.c🔧c
/**
* Command Line Arguments in C - Examples
*
* This file contains comprehensive examples demonstrating
* how to work with command line arguments in C programs.
*
* Compilation:
* gcc -Wall -o examples examples.c
*
* For getopt_long examples:
* gcc -Wall -D_GNU_SOURCE -o examples examples.c
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <unistd.h> /* For getopt */
#include <getopt.h> /* For getopt_long */
/* ============================================================
* EXAMPLE 1: Basic argc and argv
* ============================================================ */
/**
* Demonstrates the basic structure of command line arguments
*
* Usage: ./program arg1 arg2 arg3
*/
void example1_basic_argc_argv(int argc, char *argv[]) {
printf("=== Example 1: Basic argc and argv ===\n\n");
/* Print argument count */
printf("Number of arguments (argc): %d\n", argc);
printf("\n");
/* Print program name */
printf("Program name (argv[0]): %s\n", argv[0]);
printf("\n");
/* Print all arguments using array notation */
printf("All arguments (using array notation):\n");
for (int i = 0; i < argc; i++) {
printf(" argv[%d] = \"%s\"\n", i, argv[i]);
}
printf("\n");
/* Verify NULL terminator */
printf("argv[%d] is %s (should be NULL)\n",
argc, argv[argc] == NULL ? "NULL" : "NOT NULL");
printf("\n");
}
/* ============================================================
* EXAMPLE 2: Using Pointer Notation
* ============================================================ */
/**
* Demonstrates accessing arguments using pointer arithmetic
*/
void example2_pointer_notation(int argc, char **argv) {
printf("=== Example 2: Pointer Notation ===\n\n");
/* Method 1: Using pointer arithmetic */
printf("Using pointer arithmetic:\n");
char **ptr = argv;
int index = 0;
while (*ptr != NULL) {
printf(" *(argv + %d) = \"%s\"\n", index, *ptr);
ptr++;
index++;
}
printf("\n");
/* Method 2: Direct pointer increments */
printf("Using pointer increments:\n");
for (char **p = argv; *p; p++) {
printf(" %s\n", *p);
}
printf("\n");
/* Accessing individual characters */
if (argc > 1) {
printf("First argument character by character:\n");
char *arg = argv[1];
for (int i = 0; arg[i] != '\0'; i++) {
printf(" argv[1][%d] = '%c'\n", i, arg[i]);
}
}
printf("\n");
}
/* ============================================================
* EXAMPLE 3: Converting String Arguments
* ============================================================ */
/**
* Demonstrates converting command line strings to numbers
*
* Usage: ./program 42 3.14 -100
*/
void example3_string_conversion(int argc, char *argv[]) {
printf("=== Example 3: String Conversion ===\n\n");
/* atoi - simple integer conversion (no error checking) */
printf("Using atoi() - Simple but unsafe:\n");
if (argc > 1) {
int val = atoi(argv[1]);
printf(" atoi(\"%s\") = %d\n", argv[1], val);
printf(" Note: atoi returns 0 for invalid input\n");
}
printf("\n");
/* strtol - integer conversion with error checking */
printf("Using strtol() - Safe with error checking:\n");
if (argc > 1) {
char *endptr;
errno = 0;
long val = strtol(argv[1], &endptr, 10);
if (errno == ERANGE) {
printf(" Error: Number out of range\n");
} else if (endptr == argv[1]) {
printf(" Error: No digits found\n");
} else if (*endptr != '\0') {
printf(" Warning: Extra characters after number: \"%s\"\n", endptr);
printf(" Parsed value: %ld\n", val);
} else {
printf(" strtol(\"%s\", ..., 10) = %ld\n", argv[1], val);
}
}
printf("\n");
/* strtod - floating point conversion */
printf("Using strtod() - Double conversion:\n");
if (argc > 2) {
char *endptr;
errno = 0;
double val = strtod(argv[2], &endptr);
if (errno == ERANGE) {
printf(" Error: Number out of range\n");
} else if (*endptr != '\0') {
printf(" Warning: Extra characters: \"%s\"\n", endptr);
} else {
printf(" strtod(\"%s\", ...) = %f\n", argv[2], val);
}
} else {
printf(" (Need second argument for this demo)\n");
}
printf("\n");
/* Hexadecimal conversion */
printf("Hexadecimal conversion:\n");
if (argc > 1) {
char *endptr;
long val = strtol(argv[1], &endptr, 16);
printf(" As hex: strtol(\"%s\", ..., 16) = %ld (0x%lx)\n",
argv[1], val, val);
}
printf("\n");
}
/* ============================================================
* EXAMPLE 4: Simple Calculator
* ============================================================ */
/**
* A simple calculator using command line arguments
*
* Usage: ./program 10 + 5
* ./program 20 - 3
* ./program 7 x 6 (use 'x' for multiply, shell may interpret '*')
* ./program 100 / 5
*/
void example4_calculator(int argc, char *argv[]) {
printf("=== Example 4: Simple Calculator ===\n\n");
if (argc != 4) {
printf("Usage: program <num1> <operator> <num2>\n");
printf("Operators: +, -, x (multiply), /\n");
printf("Example: program 10 + 5\n");
return;
}
double num1 = atof(argv[1]);
double num2 = atof(argv[3]);
char op = argv[2][0];
double result;
int valid = 1;
switch (op) {
case '+':
result = num1 + num2;
break;
case '-':
result = num1 - num2;
break;
case 'x':
case 'X':
case '*':
result = num1 * num2;
op = '*'; /* Normalize for display */
break;
case '/':
if (num2 == 0) {
printf("Error: Division by zero!\n");
valid = 0;
} else {
result = num1 / num2;
}
break;
case '%':
if (num2 == 0) {
printf("Error: Modulo by zero!\n");
valid = 0;
} else {
result = (int)num1 % (int)num2;
}
break;
default:
printf("Error: Unknown operator '%c'\n", op);
valid = 0;
}
if (valid) {
printf("%.2f %c %.2f = %.2f\n", num1, op, num2, result);
}
printf("\n");
}
/* ============================================================
* EXAMPLE 5: Manual Argument Parsing
* ============================================================ */
/**
* Demonstrates manual parsing of command line options
*
* Usage: ./program -v -f filename -n 10 file1 file2
*/
void example5_manual_parsing(int argc, char *argv[]) {
printf("=== Example 5: Manual Argument Parsing ===\n\n");
/* Configuration */
int verbose = 0;
int number = 0;
char *filename = NULL;
char *files[10];
int file_count = 0;
/* Parse arguments */
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--verbose") == 0) {
verbose = 1;
}
else if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) {
printf("Usage: %s [options] [files...]\n", argv[0]);
printf("Options:\n");
printf(" -v, --verbose Enable verbose mode\n");
printf(" -f, --file Specify a file\n");
printf(" -n, --number Specify a number\n");
printf(" -h, --help Show this help\n");
return;
}
else if (strcmp(argv[i], "-f") == 0 || strcmp(argv[i], "--file") == 0) {
if (i + 1 < argc) {
filename = argv[++i];
} else {
printf("Error: -f requires a filename\n");
return;
}
}
else if (strcmp(argv[i], "-n") == 0 || strcmp(argv[i], "--number") == 0) {
if (i + 1 < argc) {
number = atoi(argv[++i]);
} else {
printf("Error: -n requires a number\n");
return;
}
}
else if (argv[i][0] == '-') {
printf("Unknown option: %s\n", argv[i]);
}
else {
/* Positional argument (file) */
if (file_count < 10) {
files[file_count++] = argv[i];
}
}
}
/* Display parsed options */
printf("Parsed options:\n");
printf(" Verbose: %s\n", verbose ? "yes" : "no");
printf(" Number: %d\n", number);
printf(" Filename: %s\n", filename ? filename : "(none)");
printf(" File count: %d\n", file_count);
if (file_count > 0) {
printf(" Files:\n");
for (int i = 0; i < file_count; i++) {
printf(" [%d] %s\n", i, files[i]);
}
}
printf("\n");
}
/* ============================================================
* EXAMPLE 6: Using getopt()
* ============================================================ */
/**
* Demonstrates POSIX getopt() function
*
* Usage: ./program -v -d -f filename -c 5
*/
void example6_getopt(int argc, char *argv[]) {
printf("=== Example 6: Using getopt() ===\n\n");
/* Reset getopt for reuse */
optind = 1;
opterr = 1;
int opt;
int verbose = 0;
int debug = 0;
char *filename = NULL;
int count = 1;
/*
* Option string format:
* - Single letter: flag (no argument)
* - Letter followed by ':': requires argument
* - Letter followed by '::': optional argument (GNU extension)
*/
while ((opt = getopt(argc, argv, "vdhf:c:")) != -1) {
switch (opt) {
case 'v':
verbose = 1;
printf(" Found -v (verbose)\n");
break;
case 'd':
debug = 1;
printf(" Found -d (debug)\n");
break;
case 'f':
filename = optarg;
printf(" Found -f with argument: %s\n", optarg);
break;
case 'c':
count = atoi(optarg);
printf(" Found -c with argument: %s\n", optarg);
break;
case 'h':
printf("Usage: %s [-v] [-d] [-f file] [-c count]\n", argv[0]);
return;
case '?':
printf(" Unknown option or missing argument\n");
break;
}
}
printf("\nParsed values:\n");
printf(" Verbose: %d\n", verbose);
printf(" Debug: %d\n", debug);
printf(" Filename: %s\n", filename ? filename : "(none)");
printf(" Count: %d\n", count);
/* Process remaining (non-option) arguments */
printf("\nRemaining arguments:\n");
for (int i = optind; i < argc; i++) {
printf(" argv[%d] = %s\n", i, argv[i]);
}
printf("\n");
}
/* ============================================================
* EXAMPLE 7: Using getopt_long()
* ============================================================ */
/**
* Demonstrates GNU getopt_long() for long options
*
* Usage: ./program --verbose --config=file.cfg --port 8080
*/
void example7_getopt_long(int argc, char *argv[]) {
printf("=== Example 7: Using getopt_long() ===\n\n");
/* Reset getopt for reuse */
optind = 1;
opterr = 1;
int opt;
int verbose = 0;
int debug = 0;
char *config = NULL;
int port = 8080;
/* Define long options */
static struct option long_options[] = {
{"verbose", no_argument, NULL, 'v'},
{"debug", no_argument, NULL, 'd'},
{"config", required_argument, NULL, 'c'},
{"port", required_argument, NULL, 'p'},
{"help", no_argument, NULL, 'h'},
{"version", no_argument, NULL, 'V'},
{NULL, 0, NULL, 0}
};
int option_index = 0;
while ((opt = getopt_long(argc, argv, "vdc:p:hV",
long_options, &option_index)) != -1) {
switch (opt) {
case 'v':
verbose = 1;
printf(" Found --verbose/-v\n");
break;
case 'd':
debug = 1;
printf(" Found --debug/-d\n");
break;
case 'c':
config = optarg;
printf(" Found --config/-c: %s\n", optarg);
break;
case 'p':
port = atoi(optarg);
printf(" Found --port/-p: %s\n", optarg);
break;
case 'h':
printf("Usage: %s [OPTIONS]\n\n", argv[0]);
printf("Options:\n");
printf(" -v, --verbose Verbose output\n");
printf(" -d, --debug Debug mode\n");
printf(" -c, --config=FILE Config file\n");
printf(" -p, --port=PORT Port number\n");
printf(" -h, --help This help\n");
printf(" -V, --version Version info\n");
return;
case 'V':
printf("Version 1.0.0\n");
return;
case '?':
break;
}
}
printf("\nConfiguration:\n");
printf(" Verbose: %s\n", verbose ? "enabled" : "disabled");
printf(" Debug: %s\n", debug ? "enabled" : "disabled");
printf(" Config: %s\n", config ? config : "(default)");
printf(" Port: %d\n", port);
printf("\n");
}
/* ============================================================
* EXAMPLE 8: Long Options with Flag
* ============================================================ */
/**
* Demonstrates using flag pointers with getopt_long
*/
void example8_flag_options(int argc, char *argv[]) {
printf("=== Example 8: Long Options with Flags ===\n\n");
/* Reset getopt */
optind = 1;
/* Flag variables that will be set directly */
static int verbose_flag = 0;
static int debug_flag = 0;
static int quiet_flag = 0;
static struct option long_options[] = {
/* These set flags directly (return 0) */
{"verbose", no_argument, &verbose_flag, 1},
{"debug", no_argument, &debug_flag, 1},
{"quiet", no_argument, &quiet_flag, 1},
/* These return the val character */
{"output", required_argument, NULL, 'o'},
{"help", no_argument, NULL, 'h'},
{NULL, 0, NULL, 0}
};
char *output = NULL;
int opt;
int option_index = 0;
while ((opt = getopt_long(argc, argv, "o:h",
long_options, &option_index)) != -1) {
switch (opt) {
case 0:
/* Flag was set automatically */
printf(" Option '%s' set flag\n",
long_options[option_index].name);
break;
case 'o':
output = optarg;
printf(" Output file: %s\n", optarg);
break;
case 'h':
printf("Help: Use --verbose, --debug, --quiet, --output=FILE\n");
return;
case '?':
break;
}
}
printf("\nFlag values:\n");
printf(" verbose_flag = %d\n", verbose_flag);
printf(" debug_flag = %d\n", debug_flag);
printf(" quiet_flag = %d\n", quiet_flag);
printf(" output = %s\n", output ? output : "(none)");
/* Reset flags for next call */
verbose_flag = debug_flag = quiet_flag = 0;
printf("\n");
}
/* ============================================================
* EXAMPLE 9: Error Handling with getopt
* ============================================================ */
/**
* Demonstrates proper error handling with getopt
*/
void example9_error_handling(int argc, char *argv[]) {
printf("=== Example 9: Error Handling ===\n\n");
/* Reset getopt */
optind = 1;
opterr = 0; /* Suppress automatic error messages */
int opt;
/* Leading ':' makes getopt return ':' for missing argument */
while ((opt = getopt(argc, argv, ":a:bc:")) != -1) {
switch (opt) {
case 'a':
printf(" Option -a with value: %s\n", optarg);
break;
case 'b':
printf(" Option -b\n");
break;
case 'c':
printf(" Option -c with value: %s\n", optarg);
break;
case ':':
/* Missing required argument */
fprintf(stderr, " Error: Option '-%c' requires an argument\n",
optopt);
break;
case '?':
/* Unknown option */
if (isprint(optopt)) {
fprintf(stderr, " Error: Unknown option '-%c'\n", optopt);
} else {
fprintf(stderr, " Error: Unknown option character '\\x%x'\n",
optopt);
}
break;
}
}
printf("\n");
}
/* ============================================================
* EXAMPLE 10: Environment Variables
* ============================================================ */
/**
* Demonstrates accessing environment variables
*/
void example10_environment_variables(void) {
printf("=== Example 10: Environment Variables ===\n\n");
/* Get specific environment variables */
printf("Common environment variables:\n");
const char *vars[] = {"HOME", "USER", "PATH", "SHELL", "PWD",
"TERM", "LANG", "EDITOR", NULL};
for (int i = 0; vars[i] != NULL; i++) {
char *value = getenv(vars[i]);
if (value) {
if (strlen(value) > 60) {
/* Truncate long values for display */
printf(" %s = %.57s...\n", vars[i], value);
} else {
printf(" %s = %s\n", vars[i], value);
}
} else {
printf(" %s = (not set)\n", vars[i]);
}
}
printf("\n");
}
/* ============================================================
* EXAMPLE 11: Complete CLI Application Structure
* ============================================================ */
typedef struct {
int verbose;
int force;
int recursive;
char *input_file;
char *output_file;
int count;
} AppConfig;
void init_config(AppConfig *config) {
config->verbose = 0;
config->force = 0;
config->recursive = 0;
config->input_file = NULL;
config->output_file = NULL;
config->count = 1;
}
void print_app_usage(const char *program) {
printf("Usage: %s [OPTIONS] INPUT [OUTPUT]\n\n", program);
printf("A demo command line application.\n\n");
printf("Options:\n");
printf(" -v, --verbose Enable verbose output\n");
printf(" -f, --force Force operation\n");
printf(" -r, --recursive Recursive mode\n");
printf(" -c, --count=N Set count value\n");
printf(" -o, --output=FILE Output file\n");
printf(" -h, --help Show this help\n");
printf("\nExamples:\n");
printf(" %s -v input.txt\n", program);
printf(" %s --count=5 --output=out.txt input.txt\n", program);
}
int parse_config(int argc, char *argv[], AppConfig *config) {
/* Reset getopt */
optind = 1;
static struct option long_options[] = {
{"verbose", no_argument, NULL, 'v'},
{"force", no_argument, NULL, 'f'},
{"recursive", no_argument, NULL, 'r'},
{"count", required_argument, NULL, 'c'},
{"output", required_argument, NULL, 'o'},
{"help", no_argument, NULL, 'h'},
{NULL, 0, NULL, 0}
};
int opt;
while ((opt = getopt_long(argc, argv, "vfrc:o:h",
long_options, NULL)) != -1) {
switch (opt) {
case 'v':
config->verbose = 1;
break;
case 'f':
config->force = 1;
break;
case 'r':
config->recursive = 1;
break;
case 'c':
config->count = atoi(optarg);
break;
case 'o':
config->output_file = optarg;
break;
case 'h':
return -1; /* Signal to show help */
case '?':
return -2; /* Error */
}
}
/* Get positional arguments */
if (optind < argc) {
config->input_file = argv[optind++];
}
if (optind < argc && config->output_file == NULL) {
config->output_file = argv[optind++];
}
return 0;
}
void example11_complete_application(int argc, char *argv[]) {
printf("=== Example 11: Complete CLI Application ===\n\n");
AppConfig config;
init_config(&config);
int result = parse_config(argc, argv, &config);
if (result == -1) {
print_app_usage(argv[0]);
return;
}
if (result == -2) {
printf("Error parsing arguments\n");
return;
}
/* Display configuration */
printf("Configuration:\n");
printf(" Verbose: %s\n", config.verbose ? "yes" : "no");
printf(" Force: %s\n", config.force ? "yes" : "no");
printf(" Recursive: %s\n", config.recursive ? "yes" : "no");
printf(" Count: %d\n", config.count);
printf(" Input: %s\n", config.input_file ? config.input_file : "(none)");
printf(" Output: %s\n", config.output_file ? config.output_file : "(stdout)");
printf("\n");
}
/* ============================================================
* EXAMPLE 12: Subcommands Pattern
* ============================================================ */
/**
* Demonstrates git-like subcommand pattern
*
* Usage: ./program init [options]
* ./program add <file>
* ./program status
*/
void example12_subcommands(int argc, char *argv[]) {
printf("=== Example 12: Subcommands Pattern ===\n\n");
if (argc < 2) {
printf("Usage: %s <command> [options]\n\n", argv[0]);
printf("Commands:\n");
printf(" init Initialize something\n");
printf(" add Add something\n");
printf(" remove Remove something\n");
printf(" status Show status\n");
printf(" help Show help\n");
return;
}
const char *command = argv[1];
if (strcmp(command, "init") == 0) {
printf("Executing 'init' command\n");
if (argc > 2) {
printf(" With options: ");
for (int i = 2; i < argc; i++) {
printf("%s ", argv[i]);
}
printf("\n");
}
}
else if (strcmp(command, "add") == 0) {
if (argc < 3) {
printf("Usage: %s add <item>\n", argv[0]);
return;
}
printf("Adding: %s\n", argv[2]);
}
else if (strcmp(command, "remove") == 0 || strcmp(command, "rm") == 0) {
if (argc < 3) {
printf("Usage: %s remove <item>\n", argv[0]);
return;
}
printf("Removing: %s\n", argv[2]);
}
else if (strcmp(command, "status") == 0 || strcmp(command, "st") == 0) {
printf("Showing status...\n");
printf(" Everything is OK!\n");
}
else if (strcmp(command, "help") == 0) {
printf("Showing help for ");
if (argc > 2) {
printf("'%s' command\n", argv[2]);
} else {
printf("all commands\n");
}
}
else {
printf("Unknown command: %s\n", command);
printf("Try '%s help' for usage information\n", argv[0]);
}
printf("\n");
}
/* ============================================================
* EXAMPLE 13: Argument Validation
* ============================================================ */
typedef enum {
VALIDATE_OK,
VALIDATE_ERROR_EMPTY,
VALIDATE_ERROR_RANGE,
VALIDATE_ERROR_FORMAT,
VALIDATE_ERROR_FILE
} ValidationResult;
ValidationResult validate_integer(const char *str, long min, long max, long *result) {
if (str == NULL || *str == '\0') {
return VALIDATE_ERROR_EMPTY;
}
char *endptr;
errno = 0;
long val = strtol(str, &endptr, 10);
if (errno == ERANGE || *endptr != '\0') {
return VALIDATE_ERROR_FORMAT;
}
if (val < min || val > max) {
return VALIDATE_ERROR_RANGE;
}
*result = val;
return VALIDATE_OK;
}
ValidationResult validate_file_exists(const char *filename) {
if (filename == NULL || *filename == '\0') {
return VALIDATE_ERROR_EMPTY;
}
FILE *f = fopen(filename, "r");
if (f == NULL) {
return VALIDATE_ERROR_FILE;
}
fclose(f);
return VALIDATE_OK;
}
void example13_validation(int argc, char *argv[]) {
printf("=== Example 13: Argument Validation ===\n\n");
/* Validate integer argument */
if (argc > 1) {
long value;
ValidationResult result = validate_integer(argv[1], 1, 100, &value);
switch (result) {
case VALIDATE_OK:
printf("Integer validation: OK (value = %ld)\n", value);
break;
case VALIDATE_ERROR_EMPTY:
printf("Integer validation: Empty string\n");
break;
case VALIDATE_ERROR_RANGE:
printf("Integer validation: Out of range (1-100)\n");
break;
case VALIDATE_ERROR_FORMAT:
printf("Integer validation: Invalid format\n");
break;
default:
break;
}
} else {
printf("Provide a number argument to test validation\n");
}
/* Validate file argument */
if (argc > 2) {
ValidationResult result = validate_file_exists(argv[2]);
switch (result) {
case VALIDATE_OK:
printf("File validation: '%s' exists\n", argv[2]);
break;
case VALIDATE_ERROR_FILE:
printf("File validation: '%s' not found\n", argv[2]);
break;
default:
printf("File validation: Invalid filename\n");
}
}
printf("\n");
}
/* ============================================================
* EXAMPLE 14: Reading from stdin When No File Given
* ============================================================ */
/**
* Demonstrates the common pattern of reading from stdin
* when no filename is provided (like cat, grep, etc.)
*/
void example14_stdin_fallback(int argc, char *argv[]) {
printf("=== Example 14: stdin Fallback ===\n\n");
printf("This example shows how to read from stdin when no file is given.\n");
printf("Common in tools like cat, grep, sort, etc.\n\n");
printf("Pattern:\n");
printf(" FILE *input = stdin;\n");
printf(" if (argc > 1 && strcmp(argv[1], \"-\") != 0) {\n");
printf(" input = fopen(argv[1], \"r\");\n");
printf(" if (!input) { perror(argv[1]); return 1; }\n");
printf(" }\n");
printf(" // Process input...\n");
printf(" if (input != stdin) fclose(input);\n\n");
/* Actual demonstration with simulated input */
printf("Try running: echo 'hello world' | ./program\n");
printf("Or: ./program filename.txt\n");
printf("\n");
}
/* ============================================================
* EXAMPLE 15: Multiple Input Files
* ============================================================ */
/**
* Demonstrates processing multiple input files
*
* Usage: ./program file1.txt file2.txt file3.txt
*/
void example15_multiple_files(int argc, char *argv[]) {
printf("=== Example 15: Multiple Input Files ===\n\n");
if (argc < 2) {
printf("Usage: %s file1 [file2] [file3] ...\n", argv[0]);
printf("Process multiple files like: cat, grep, wc\n");
return;
}
int total_lines = 0;
int total_files = 0;
for (int i = 1; i < argc; i++) {
const char *filename = argv[i];
/* Handle "-" as stdin */
if (strcmp(filename, "-") == 0) {
printf("Would read from stdin\n");
continue;
}
/* Try to open file */
FILE *f = fopen(filename, "r");
if (!f) {
fprintf(stderr, "%s: %s: %s\n", argv[0], filename, strerror(errno));
continue;
}
/* Count lines */
int lines = 0;
int c;
while ((c = fgetc(f)) != EOF) {
if (c == '\n') lines++;
}
printf("%s: %d lines\n", filename, lines);
total_lines += lines;
total_files++;
fclose(f);
}
if (total_files > 1) {
printf("Total: %d files, %d lines\n", total_files, total_lines);
}
printf("\n");
}
/* ============================================================
* MAIN - Run Selected Example
* ============================================================ */
void print_menu(void) {
printf("Command Line Arguments Examples\n");
printf("================================\n\n");
printf("Select an example to run:\n\n");
printf(" 1. Basic argc and argv\n");
printf(" 2. Pointer notation\n");
printf(" 3. String conversion\n");
printf(" 4. Simple calculator\n");
printf(" 5. Manual argument parsing\n");
printf(" 6. Using getopt()\n");
printf(" 7. Using getopt_long()\n");
printf(" 8. Long options with flags\n");
printf(" 9. Error handling\n");
printf(" 10. Environment variables\n");
printf(" 11. Complete CLI application\n");
printf(" 12. Subcommands pattern\n");
printf(" 13. Argument validation\n");
printf(" 14. stdin fallback\n");
printf(" 15. Multiple input files\n");
printf(" 0. Run all examples\n");
printf("\n");
}
int main(int argc, char *argv[]) {
int choice = -1;
/* If no arguments, show menu and read choice */
if (argc < 2) {
print_menu();
printf("Enter example number: ");
if (scanf("%d", &choice) != 1) {
printf("Invalid input\n");
return 1;
}
printf("\n");
} else {
choice = atoi(argv[1]);
}
/* Create sample arguments for demos */
char *sample_args[] = {
"./program", "-v", "--verbose", "-f", "file.txt",
"-n", "42", "extra1", "extra2", "3.14",
"--config=test.cfg", "--port", "8080", NULL
};
int sample_argc = 13;
switch (choice) {
case 0:
/* Run all */
example1_basic_argc_argv(argc > 2 ? argc - 1 : sample_argc,
argc > 2 ? argv + 1 : sample_args);
example2_pointer_notation(argc > 2 ? argc - 1 : sample_argc,
argc > 2 ? argv + 1 : sample_args);
example3_string_conversion(argc > 2 ? argc - 1 : sample_argc,
argc > 2 ? argv + 1 : sample_args);
example4_calculator(5, (char*[]){"calc", "10", "+", "5", NULL});
example5_manual_parsing(sample_argc, sample_args);
example6_getopt(sample_argc, sample_args);
example7_getopt_long(sample_argc, sample_args);
example8_flag_options(5, (char*[]){"prog", "--verbose",
"--debug", "-o", "out.txt", NULL});
example9_error_handling(sample_argc, sample_args);
example10_environment_variables();
example11_complete_application(sample_argc, sample_args);
example12_subcommands(3, (char*[]){"prog", "add", "item", NULL});
example13_validation(3, (char*[]){"prog", "50", "examples.c", NULL});
example14_stdin_fallback(argc, argv);
example15_multiple_files(2, (char*[]){"prog", "examples.c", NULL});
break;
case 1:
example1_basic_argc_argv(argc > 2 ? argc - 1 : sample_argc,
argc > 2 ? argv + 1 : sample_args);
break;
case 2:
example2_pointer_notation(argc > 2 ? argc - 1 : sample_argc,
argc > 2 ? argv + 1 : sample_args);
break;
case 3:
example3_string_conversion(argc > 2 ? argc - 1 : sample_argc,
argc > 2 ? argv + 1 : sample_args);
break;
case 4:
example4_calculator(5, (char*[]){"calc", "10", "+", "5", NULL});
break;
case 5:
example5_manual_parsing(sample_argc, sample_args);
break;
case 6:
example6_getopt(sample_argc, sample_args);
break;
case 7:
example7_getopt_long(sample_argc, sample_args);
break;
case 8:
example8_flag_options(5, (char*[]){"prog", "--verbose",
"--debug", "-o", "out.txt", NULL});
break;
case 9:
example9_error_handling(sample_argc, sample_args);
break;
case 10:
example10_environment_variables();
break;
case 11:
example11_complete_application(sample_argc, sample_args);
break;
case 12:
example12_subcommands(3, (char*[]){"prog", "add", "item", NULL});
break;
case 13:
example13_validation(3, (char*[]){"prog", "50", "examples.c", NULL});
break;
case 14:
example14_stdin_fallback(argc, argv);
break;
case 15:
example15_multiple_files(2, (char*[]){"prog", "examples.c", NULL});
break;
default:
printf("Invalid choice. Run without arguments to see menu.\n");
return 1;
}
return 0;
}