Introduction
Command line arguments allow programs to receive input parameters when they are executed from the command line. This feature enables users to pass information to programs without requiring interactive input, making programs more flexible and suitable for automation and scripting. In C, command line arguments are accessed through the main function parameters.
Key Concepts
argc: Argument count - number of command line arguments passed argv: Argument vector - array of strings containing the arguments argv[0]: Always contains the program name Command Line Interface: Text-based interface for program execution
Basic Syntax
Main Function with Command Line Arguments
#include <stdio.h>
int main(int argc, char *argv[]) {
printf("Number of arguments: %d\n", argc);
printf("Arguments:\n");
for (int i = 0; i < argc; i++) {
printf("argv[%d] = %s\n", i, argv[i]);
}
return 0;
}
/*
Example execution and output:
$ ./program hello world 123
Number of arguments: 4
Arguments:
argv[0] = ./program
argv[1] = hello
argv[2] = world
argv[3] = 123
*/
Alternative Declaration Syntax
#include <stdio.h>
// Alternative ways to declare main function
int main(int argc, char **argv) {
// Same functionality as char *argv[]
printf("Program name: %s\n", argv[0]);
return 0;
}
// Using different parameter names
int main(int arg_count, char *arg_values[]) {
printf("Total arguments: %d\n", arg_count);
return 0;
}
Basic Examples
Simple Argument Display
#include <stdio.h>
int main(int argc, char *argv[]) {
if (argc == 1) {
printf("No arguments provided.\n");
printf("Usage: %s <arguments>\n", argv[0]);
return 1;
}
printf("Program: %s\n", argv[0]);
printf("Arguments provided:\n");
for (int i = 1; i < argc; i++) {
printf("%d: %s\n", i, argv[i]);
}
return 0;
}
/*
Example usage:
$ ./program apple banana cherry
Program: ./program
Arguments provided:
1: apple
2: banana
3: cherry
*/
Argument Processing
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[]) {
printf("=== Command Line Argument Processor ===\n");
printf("Program executed: %s\n", argv[0]);
printf("Total arguments (including program name): %d\n", argc);
if (argc > 1) {
printf("\nProcessing arguments:\n");
for (int i = 1; i < argc; i++) {
printf("Argument %d: '%s' (Length: %zu)\n",
i, argv[i], strlen(argv[i]));
}
} else {
printf("No command line arguments provided.\n");
}
return 0;
}
Practical Applications
Calculator Program
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]) {
if (argc != 4) {
printf("Usage: %s <number1> <operator> <number2>\n", argv[0]);
printf("Operators: +, -, *, /\n");
printf("Example: %s 10 + 5\n", argv[0]);
return 1;
}
double num1 = atof(argv[1]);
char operator = argv[2][0];
double num2 = atof(argv[3]);
double result;
switch (operator) {
case '+':
result = num1 + num2;
printf("%.2f + %.2f = %.2f\n", num1, num2, result);
break;
case '-':
result = num1 - num2;
printf("%.2f - %.2f = %.2f\n", num1, num2, result);
break;
case '*':
result = num1 * num2;
printf("%.2f * %.2f = %.2f\n", num1, num2, result);
break;
case '/':
if (num2 != 0) {
result = num1 / num2;
printf("%.2f / %.2f = %.2f\n", num1, num2, result);
} else {
printf("Error: Division by zero!\n");
return 1;
}
break;
default:
printf("Error: Unknown operator '%c'\n", operator);
printf("Supported operators: +, -, *, /\n");
return 1;
}
return 0;
}
/*
Example usage:
$ ./calculator 15 * 4
15.00 * 4.00 = 60.00
$ ./calculator 100 / 7
100.00 / 7.00 = 14.29
*/
File Operations Program
#include <stdio.h>
#include <string.h>
void displayFileInfo(char *filename) {
FILE *file = fopen(filename, "r");
if (file == NULL) {
printf("Error: Cannot open file '%s'\n", filename);
return;
}
int lines = 0, characters = 0, words = 0;
char ch;
int inWord = 0;
while ((ch = fgetc(file)) != EOF) {
characters++;
if (ch == '\n') {
lines++;
}
if (ch == ' ' || ch == '\t' || ch == '\n') {
if (inWord) {
words++;
inWord = 0;
}
} else {
inWord = 1;
}
}
if (inWord) words++; // Count last word if file doesn't end with whitespace
fclose(file);
printf("File: %s\n", filename);
printf("Lines: %d\n", lines);
printf("Words: %d\n", words);
printf("Characters: %d\n", characters);
printf("---\n");
}
int main(int argc, char *argv[]) {
if (argc < 2) {
printf("Usage: %s <file1> [file2] [file3] ...\n", argv[0]);
printf("This program displays statistics for text files.\n");
return 1;
}
printf("=== File Statistics ===\n");
for (int i = 1; i < argc; i++) {
displayFileInfo(argv[i]);
}
return 0;
}
Search Program
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[]) {
if (argc < 3) {
printf("Usage: %s <search_term> <string1> [string2] ...\n", argv[0]);
printf("Searches for a term in provided strings.\n");
return 1;
}
char *searchTerm = argv[1];
int found = 0;
printf("Searching for '%s' in provided strings:\n", searchTerm);
for (int i = 2; i < argc; i++) {
if (strstr(argv[i], searchTerm) != NULL) {
printf("✓ Found in string %d: '%s'\n", i-1, argv[i]);
found++;
} else {
printf("✗ Not found in string %d: '%s'\n", i-1, argv[i]);
}
}
printf("\nSummary: '%s' found in %d out of %d strings.\n",
searchTerm, found, argc - 2);
return 0;
}
/*
Example usage:
$ ./search "ing" "programming" "hello" "testing" "world"
Searching for 'ing' in provided strings:
✓ Found in string 1: 'programming'
✗ Not found in string 2: 'hello'
✓ Found in string 3: 'testing'
✗ Not found in string 4: 'world'
Summary: 'ing' found in 2 out of 4 strings.
*/
Advanced Examples
Option Processing with Flags
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct {
int verbose;
int help;
char *output_file;
char *input_file;
} Options;
void printHelp(char *program_name) {
printf("Usage: %s [OPTIONS] <input_file>\n", program_name);
printf("Options:\n");
printf(" -v, --verbose Enable verbose output\n");
printf(" -h, --help Show this help message\n");
printf(" -o <file> Specify output file\n");
printf("Example: %s -v -o output.txt input.txt\n", program_name);
}
int parseArguments(int argc, char *argv[], Options *opts) {
// Initialize options
opts->verbose = 0;
opts->help = 0;
opts->output_file = NULL;
opts->input_file = NULL;
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--verbose") == 0) {
opts->verbose = 1;
} else if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) {
opts->help = 1;
} else if (strcmp(argv[i], "-o") == 0) {
if (i + 1 < argc) {
opts->output_file = argv[++i];
} else {
printf("Error: -o requires a filename\n");
return 0;
}
} else if (argv[i][0] == '-') {
printf("Error: Unknown option '%s'\n", argv[i]);
return 0;
} else {
if (opts->input_file == NULL) {
opts->input_file = argv[i];
} else {
printf("Error: Multiple input files specified\n");
return 0;
}
}
}
return 1;
}
int main(int argc, char *argv[]) {
Options opts;
if (!parseArguments(argc, argv, &opts)) {
return 1;
}
if (opts.help || argc == 1) {
printHelp(argv[0]);
return 0;
}
if (opts.input_file == NULL) {
printf("Error: No input file specified\n");
printHelp(argv[0]);
return 1;
}
// Process based on options
if (opts.verbose) {
printf("Verbose mode enabled\n");
printf("Input file: %s\n", opts.input_file);
if (opts.output_file) {
printf("Output file: %s\n", opts.output_file);
} else {
printf("Output: stdout\n");
}
}
printf("Processing file: %s\n", opts.input_file);
// Add actual file processing logic here
return 0;
}
Number Statistics Program
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
if (argc < 2) {
printf("Usage: %s <number1> [number2] [number3] ...\n", argv[0]);
printf("Calculates statistics for provided numbers.\n");
return 1;
}
int count = argc - 1;
double *numbers = malloc(count * sizeof(double));
double sum = 0.0, min, max;
// Parse and store numbers
for (int i = 1; i < argc; i++) {
numbers[i-1] = atof(argv[i]);
sum += numbers[i-1];
if (i == 1) {
min = max = numbers[i-1];
} else {
if (numbers[i-1] < min) min = numbers[i-1];
if (numbers[i-1] > max) max = numbers[i-1];
}
}
double average = sum / count;
// Calculate standard deviation
double variance = 0.0;
for (int i = 0; i < count; i++) {
variance += (numbers[i] - average) * (numbers[i] - average);
}
variance /= count;
double std_dev = sqrt(variance);
// Display results
printf("=== Number Statistics ===\n");
printf("Count: %d\n", count);
printf("Sum: %.2f\n", sum);
printf("Average: %.2f\n", average);
printf("Minimum: %.2f\n", min);
printf("Maximum: %.2f\n", max);
printf("Standard Deviation: %.2f\n", std_dev);
printf("\nNumbers processed: ");
for (int i = 0; i < count; i++) {
printf("%.2f ", numbers[i]);
}
printf("\n");
free(numbers);
return 0;
}
/*
Example usage:
$ ./stats 10 20 15 25 12 18
=== Number Statistics ===
Count: 6
Sum: 100.00
Average: 16.67
Minimum: 10.00
Maximum: 25.00
Standard Deviation: 5.27
Numbers processed: 10.00 20.00 15.00 25.00 12.00 18.00
*/
Validation and Error Handling
Robust Argument Validation
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int isValidNumber(char *str) {
if (str == NULL || strlen(str) == 0) return 0;
int i = 0;
if (str[0] == '-' || str[0] == '+') i = 1;
int hasDigit = 0, hasDecimal = 0;
for (; i < strlen(str); i++) {
if (isdigit(str[i])) {
hasDigit = 1;
} else if (str[i] == '.' && !hasDecimal) {
hasDecimal = 1;
} else {
return 0;
}
}
return hasDigit;
}
int main(int argc, char *argv[]) {
if (argc < 3) {
printf("Usage: %s <operation> <number1> [number2] ...\n", argv[0]);
printf("Operations: sum, avg, min, max\n");
return 1;
}
char *operation = argv[1];
// Validate operation
if (strcmp(operation, "sum") != 0 && strcmp(operation, "avg") != 0 &&
strcmp(operation, "min") != 0 && strcmp(operation, "max") != 0) {
printf("Error: Invalid operation '%s'\n", operation);
printf("Valid operations: sum, avg, min, max\n");
return 1;
}
// Validate all numbers
for (int i = 2; i < argc; i++) {
if (!isValidNumber(argv[i])) {
printf("Error: '%s' is not a valid number\n", argv[i]);
return 1;
}
}
// Process numbers
int count = argc - 2;
double result;
double first_num = atof(argv[2]);
if (strcmp(operation, "sum") == 0 || strcmp(operation, "avg") == 0) {
result = 0.0;
for (int i = 2; i < argc; i++) {
result += atof(argv[i]);
}
if (strcmp(operation, "avg") == 0) {
result /= count;
}
} else if (strcmp(operation, "min") == 0) {
result = first_num;
for (int i = 3; i < argc; i++) {
double num = atof(argv[i]);
if (num < result) result = num;
}
} else if (strcmp(operation, "max") == 0) {
result = first_num;
for (int i = 3; i < argc; i++) {
double num = atof(argv[i]);
if (num > result) result = num;
}
}
printf("Operation: %s\n", operation);
printf("Numbers: ");
for (int i = 2; i < argc; i++) {
printf("%s ", argv[i]);
}
printf("\nResult: %.2f\n", result);
return 0;
}
Best Practices
Defensive Programming
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_FILENAME_LENGTH 256
int main(int argc, char *argv[]) {
// Always check argument count first
if (argc < 2) {
fprintf(stderr, "Error: Insufficient arguments\n");
fprintf(stderr, "Usage: %s <filename>\n", argv[0]);
return EXIT_FAILURE;
}
// Validate argument length
if (strlen(argv[1]) >= MAX_FILENAME_LENGTH) {
fprintf(stderr, "Error: Filename too long (max %d characters)\n",
MAX_FILENAME_LENGTH - 1);
return EXIT_FAILURE;
}
// Validate filename characters (basic check)
char *filename = argv[1];
for (int i = 0; filename[i] != '\0'; i++) {
if (filename[i] == '\0' || filename[i] < 32 || filename[i] > 126) {
fprintf(stderr, "Error: Invalid character in filename\n");
return EXIT_FAILURE;
}
}
printf("Processing file: %s\n", filename);
// Add file processing logic here
return EXIT_SUCCESS;
}
Common Use Cases
- Configuration Programs: Accepting config file paths
- Batch Processing: Processing multiple files
- Calculators: Mathematical operations with numbers
- Text Processors: Search, replace, format operations
- System Utilities: File management, system monitoring
- Data Analysis: Statistical operations on datasets
Common Mistakes
- Not checking argc: Always validate argument count
- Array bounds: Remember argv[0] is program name
- Type conversion: Validate before using atoi(), atof()
- Memory management: Free allocated memory for large argument processing
- Error messages: Provide helpful usage information
Summary
Command line arguments provide a powerful way to make C programs flexible and user-friendly. They enable programs to accept input parameters, configuration options, and file paths without requiring interactive input. Proper validation, error handling, and user-friendly help messages are essential for creating robust command-line programs. Understanding argc and argv is fundamental for developing professional-quality C applications.
Part of BCA Programming with C Course (UGCOA22J201)