Skip to Content
Course content

186: Parsing Command-Line Arguments with argc/argv

Click on the "Edit" button in the top corner of the screen to edit your slide content.

I've seen this exact crash more times than I can count, even from developers who have been writing C for a year or two. You're building a tool that's supposed to take a filename as an argument, you run it, and—boom—Segmentation fault (core dumped). Let's look at the culprit.

# This is broken code. Do not run this without arguments!
# word_count.c
#include <stdio.h>

int main(int argc, char *argv[]) {
    // We assume the user passed a filename as the first argument
    FILE *file = fopen(argv[1], "r"); 
    
    if (file == NULL) {
        printf("Could not open file.\n");
        return 1;
    }

    printf("File opened successfully!\n");
    fclose(file);
    return 0;
}

The Segfault When No File is Provided

If you compile this and run it as ./word_count (without any arguments), it will crash. Why? Because you're accessing argv[1] before checking if it even exists.

In C, argv is an array of strings. argv[0] is always the name of the program itself. If the user provides no additional arguments, argv[1] is a NULL pointer. When you pass that NULL pointer directly into fopen(), the program tries to read a memory address that it doesn't own, and the OS shuts you down instantly. This is the classic "trusting the user" mistake.

Guarding Your Array Access with argc

The fix is simple: always check argc (the argument count) before you touch argv. argc tells you exactly how many elements are in the argv array. If you expect one argument from the user, argc must be at least 2 (the program name + the argument).

# The fixed version
# word_count.c
#include <stdio.h>

int main(int argc, char *argv[]) {
    // First, verify we actually have the filename
    if (argc < 2) {
        fprintf(stderr, "Usage: %s <filename>\n", argv[0]);
        return 1;
    }

    // Now it's safe to access argv[1]
    FILE *file = fopen(argv[1], "r");
    
    if (file == NULL) {
        perror("Error opening file");
        return 1;
    }

    printf("File %s opened successfully!\n", argv[1]);
    fclose(file);
    return 0;
}

Notice I used argv[0] in the error message. I do this because the user might have renamed your binary to something else, and it's a professional touch to show them the actual name of the command they typed incorrectly.

Converting String Arguments to Numbers

Here is the tricky part: argv is an array of char*. Everything coming from the command line is a string. If you want your program to take a number—say, a "repeat count" for a print loop—you can't just cast it to an int. You have to parse it.

I usually recommend atoi (ASCII to Integer) for quick-and-dirty tools, though it's not the most robust for production code because it doesn't handle errors well. Still, for most of your learning projects, it's the way to go.

#include <stdio.h>
#include <stdlib.h> // Required for atoi

int main(int argc, char *argv[]) {
    if (argc < 3) {
        printf("Usage: %s <name> <count>\n", argv[0]);
        return 1;
    }

    char *name = argv[1];
    int count = atoi(argv[2]); // Convert string "5" to integer 5

    for (int i = 0; i < count; i++) {
        printf("%s\n", name);
    }

    return 0;
}

One last tip: always remember that argv[argc] is guaranteed to be NULL. This is a useful property if you're writing a loop to print out all arguments without knowing the count beforehand, though using argc is the standard, cleaner way to do it.




📋 Practical Task

Build a Command-Line "String Repeater" Utility

Create a program called repeater.c that takes two command-line arguments: a string and a positive integer. The program should print that string to the console the specified number of times, each on a new line.

Your implementation must:

  • Check if exactly two arguments (plus the program name) were provided. If not, print a "Usage" message and exit with a non-zero status.
  • Convert the second argument from a string to an integer.
  • Handle the case where the user provides a number less than or equal to zero (the program should simply print nothing and exit gracefully).
  • Use argv[0] in your usage message to make the tool feel professional.
Rating
0 0

There are no comments for now.

to be the first to leave a comment.