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.
| Expression | Value for this run |
|---|---|
argc | 3 |
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 maplegivesargc == 2. The supplied word is at index 1. - Using
i <= argcto 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
%sforargv[1]and%cforargv[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 command | Meaning |
|---|---|
gcc -o program program.c | Build the executable |
argc | Argument 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] + j | Pointer 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.
- For
./inspect ocean sky, what areargcandargv[2]? - For that run, what does
printf("%s\n", argv[1] + 1);print? - What character is
*(*(argv + 2) + 1)? - In a fresh run, what prints after
argv[1][2] = '\0';followed byprintf("%s\n", argv[1]);? - A program accesses
argv[1][4]after checking onlyargc > 1. What check is still missing?
Answers
Show answers and reasoning
argc == 3, andargv[2]points to"sky". Include the program name in the count.cean. The pointer starts one character past theo.'k'. Select argument 2, then character index 1.oc. The new terminator at index 2 replacese.- 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.