CSSE 132 Mini-reading ยท Task 12

Command-line Arguments in C in 10 Minutes

Follow the arguments from a shell command into main, then trace pointers and characters inside each argument string.

Why This Matters

When you run a C program from the terminal, you can supply information on the same command line. The program receives that information through the parameters of main. Worksheet 12 combines this idea with string indexing and pointer arithmetic, so you need to track both which argument you selected and where you are inside its string.

Core Idea

int main(int argc, char** argv)

argc counts the argument strings, including the program name. argv points to an array of character pointers. Each entry points to the first character of one string. You may also see this parameter written as char* argv[] in a declaration of main.

Choose an argument

argv[1] selects the first argument after the program name. Its type is char*, so it points to a string.

Choose a character

argv[1][2] selects character index 2 in that string. Its type is char. Both indexes start at zero.

Keep these two levels separate: the outer array holds pointers, and each pointed-to string holds characters ending with '\0'. That terminator tells string operations where the text stops. There is also a null pointer at argv[argc], marking the end of the pointer array. It is not another argument string.

Worked Examples

Example 1: Compile, run, and count

gcc -o showargs showargs.c
./showargs maple cedar

The first command compiles and links showargs.c into the executable showargs. The second command runs it. The arguments to gcc belong to the compiler invocation; they are not the arguments received by showargs.

ExpressionValue for this run
argc3
argv[0]Points to "./showargs"
argv[1]Points to "maple"
argv[2]Points to "cedar"
argv[3]Null pointer

There are two supplied words plus the program name, so the count is three. Quotation marks can group words: ./showargs "red maple" cedar still produces three argument strings. The grouping quotes themselves are not part of the string.

#include <stdio.h>

int main(int argc, char** argv) {
    for (int i = 0; i < argc; i++) {
        printf("%s\n", argv[i]);
    }
    return 0;
}

For the original run, this prints ./showargs, maple, and cedar on separate lines. The condition i < argc visits every valid string entry and stops before the null pointer.

Example 2: Move through pointers, then through characters

For the same command, follow these expressions one step at a time:

*(argv + 1)       /* same as argv[1]: points to "maple" */
argv[1] + 2       /* points to the 'p' inside "maple" */
*(argv[1] + 2)    /* the character 'p' */

argv + 1 advances by one pointer entry. Dereferencing it retrieves a char*. Adding 2 to that character pointer advances by two characters, from m past a to p. On the course ARM64 system a pointer occupies eight bytes, while a char occupies one byte; pointer arithmetic scales automatically to the pointed-to type.

printf("%s\n", argv[1] + 2);  /* prints ple */
printf("%c\n", argv[1][2]);   /* prints p */

%s follows a character pointer until it reaches '\0'. Starting at p therefore prints the suffix ple. %c prints just the selected character. Moving the pointer does not change the original string.

Example 3: Change where a string ends

char* ptr = *(argv + 2);  /* points to "cedar" */
*(ptr + 3) = '\0';        /* replaces the 'a' */
printf("%s\n", ptr);     /* prints ced */

The characters originally occupy indexes 0 through 4, with the terminator at index 5. Writing a terminator at index 3 makes printing stop after d. The later r remains in memory, but this string now ends earlier. C permits modifying argument strings. This differs from moving a pointer: the assignment changes a character in the existing string.

Before accessing argv[2], ensure that argc > 2. Before writing character index 3, ensure that the selected string has that position. A valid argument index does not guarantee a valid character index.

Common Mistakes

  • Forgetting the program name. ./showargs maple gives argc == 2. The supplied word is at index 1.
  • Using i <= argc to print arguments. The final iteration selects a null pointer, which is not a valid string for %s.
  • Confusing a string pointer with a character. Use %s for argv[1] and %c for argv[1][0].
  • Advancing beyond a string. A pointer offset or character write needs a bounds check against that string's length. The worksheet's supplied inputs make its offsets valid; arbitrary inputs may not.

Quick Reference

Expression or commandMeaning
gcc -o program program.cBuild the executable
argcArgument count including the program name
argv[i] == *(argv + i)Two ways to select the same argument pointer
argv[i][j] == *(*(argv + i) + j)Two ways to select the same character
argv[i] + jPointer to a suffix, if the offset is within the string
'\0'Character that ends a C string

Check Yourself

Try these before opening the answers. These are fresh practice examples for the same skills used in Worksheet 12.

  1. For ./inspect ocean sky, what are argc and argv[2]?
  2. For that run, what does printf("%s\n", argv[1] + 1); print?
  3. What character is *(*(argv + 2) + 1)?
  4. In a fresh run, what prints after argv[1][2] = '\0'; followed by printf("%s\n", argv[1]);?
  5. A program accesses argv[1][4] after checking only argc > 1. What check is still missing?

Answers

Show answers and reasoning
  1. argc == 3, and argv[2] points to "sky". Include the program name in the count.
  2. cean. The pointer starts one character past the o.
  3. 'k'. Select argument 2, then character index 1.
  4. oc. The new terminator at index 2 replaces e.
  5. Check the string length. Index 4 contains an ordinary character only when the string has at least five characters. A four-character string has its terminator there; a shorter string makes the access out of bounds.