getopt(3)
๐ธ NAME ๐ธ
getopt, optarg, optind, opterr, optopt โ bestie, this is the function that parses your command-line options for you ๐
๐ซถ LIBRARY ๐ซถ
Standard C library (libc, link it with -lc)
โจ SYNOPSIS โจ
#include <unistd.h>
int getopt(int argc, char *argv[],
const char *optstring);
extern char *optarg;
extern int optind, opterr, optopt;
๐ Feature Test Macro Requirements for glibc ๐
(go check feature_test_macros(7) if you're nosy about these)
getopt():_POSIX_C_SOURCE >= 2 || _XOPEN_SOURCE
๐ DESCRIPTION ๐
Okay so getopt() parses the command-line arguments. Their arguments argc and argv are literally the argument count and the argument array just as they got passed to your main() when the program got invoked. An element of argv that starts with - โ and is not exactly "-" or "--" โ is an option element, no cap. The characters inside that element (aside from that leading -) are the option characters. And if you call getopt() in a loop over and over, it just hands you each option character from each option element, one at a time. Iconic.
The variable optind is the index of the next element in argv that's gonna get processed. The system initializes it to 1. You can reset it back to 1 to restart scanning the same argv, or whenever you're scanning a brand new argument vector. Slay.
If getopt() finds another option character, it returns that character, and it updates the external variable optind plus a static variable nextchar so that the next call to getopt() can pick up right where it left off โ with the next option character or the next argv-element. Obsessed with the continuity honestly.
If there are no more option characters, getopt() returns -1. And at that point optind is the index in argv of the first argv-element that is not an option. ๐ฆ
optstring is a string holding all the legitimate option characters. And a legitimate option character is, like, any visible one-byte ascii(7) character (one where isgraph(3) would return nonzero, iykyk) that isn't '-', ':', or ';'. If one of those characters is followed by a colon, then that option requires an argument, so getopt() puts a pointer to the following text โ either the text in that same argv-element, or the text of the following argv-element โ into optarg.
Two colons mean the option takes an optional arg. In that case, if there's text in the current argv-element (like, in the same word as the option name itself, for example "-oarg"), then it gets returned in optarg; otherwise optarg is set to zero. Heads up: this is a GNU extension โจ
If optstring contains W followed by a semicolon, then -W foo gets treated as the long option --foo. (The -W option is reserved by POSIX.2 for implementation extensions, so don't get weird with it.) This behavior is a GNU extension too โ and it's not available with libraries before glibc 2 โ ๏ธ
By default, getopt() permutes the contents of argv as it scans, so eventually all the nonoptions end up at the end. But there are two other scanning modes implemented as well:
- If the first character of
optstringis'+', or the environment variablePOSIXLY_CORRECTis set, then option processing stops the moment a nonoption argument shows up. And if'+'is not the first character ofoptstring, it's treated as a normal option. So if you need that POSIXLY_CORRECT behavior in that case,optstringis gonna contain two'+'symbols. - If the first character of
optstringis'-', then every nonoptionargv-element gets handled as if it were the argument of an option whose character code is1. (This one is used by programs that were written expecting options and otherargv-elements in any order, and that genuinely care about the ordering of the two.)
The special argument "--" forces an end to option-scanning regardless of whatever scanning mode you're in, periodt.
While it's processing the option list, getopt() can detect two kinds of errors:
- an option character that wasn't specified in
optstring, and - a missing option argument (i.e., an option sitting at the end of the command line without the argument it expected ๐ฅบ)
These errors get handled and reported like this:
- By default,
getopt()prints an error message on standard error, places the erroneous option character inoptopt, and returns'?'as the function result. - If the caller has set the global variable
opterrto zero, thengetopt()does not print an error message. The caller can figure out that there was an error by testing whether the return value is'?'. (By default,opterrhas a nonzero value.) - If the first character (following any optional
'+'or'-'described above) ofoptstringis a colon (':'), thengetopt()likewise does not print an error message. And on top of that, it returns':'instead of'?'to signal a missing option argument. This is the move that lets the caller tell the two different types of errors apart ๐
๐ฅ RETURN VALUE ๐ฅ
If an option was successfully found, then getopt() returns the option character. If all command-line options have been parsed, then getopt() returns -1. If getopt() encounters an option character that wasn't in optstring, then '?' is returned. And if getopt() encounters an option with a missing argument, then the return value depends on the first character in optstring: if it's ':', then ':' is returned; otherwise '?' is returned.
๐ ENVIRONMENT ๐
POSIXLY_CORRECTโ if this is set, then option processing stops the second a nonoption argument is encountered.
๐ ATTRIBUTES ๐
For an explanation of all the terms used in this section, go peek at attributes(7).
- Interface:
getopt() - Attribute: Thread safety
- Value:
MT-Unsafe race:getopt env
๐ฆ VERSIONS ๐ฆ
POSIX specifies that the argv array argument should be const, but these functions permute its elements unless the environment variable POSIXLY_CORRECT is set. const is used in the actual prototype so it stays compatible with other systems; however, this page doesn't show the qualifier, just to avoid confusing readers. Bestie behavior honestly.
๐ STANDARDS ๐
getopt()โ POSIX.1-2008.- The use of
'+'and'-'inoptstringis a GNU extension.
- The use of
๐ HISTORY ๐
getopt()โ POSIX.1-2001, and POSIX.2.
On some older implementations, getopt() was declared in <stdio.h>. SUSv1 permitted the declaration to appear in either <unistd.h> or <stdio.h>. POSIX.1-1996 marked the use of <stdio.h> for this purpose as LEGACY ๐. POSIX.1-2001 does not require the declaration to appear in <stdio.h>.
Very old versions of glibc were affected by a _PID_GNU_nonoption_argv_flags_ environment variable. Ancient lore fr fr.
๐ NOTES ๐
A program that scans multiple argument vectors, or rescans the same vector more than once, and that wants to make use of GNU extensions like '+' and '-' at the start of optstring, or that changes the value of POSIXLY_CORRECT between scans, must reinitialize getopt() by resetting optind to 0 โ not the traditional value of 1. (Resetting to 0 forces the invocation of an internal initialization routine that rechecks POSIXLY_CORRECT and checks for GNU extensions in optstring.) Don't skip this step, it's giving "I read the docs" energy โจ
Command-line arguments are parsed in strict order, meaning that an option requiring an argument will consume the next argument, regardless of whether that argument is the correctly specified option argument or simply the next option โ in the scenario where the user mis-specifies the command line ๐ญ. For example, if optstring is specified as "1n:" and the user specifies the command line arguments incorrectly as prog -n -1, the -n option will be given the optarg value "-1", and the -1 option will be considered to have not been specified.
โญ EXAMPLES โญ
๐ getopt() ๐
The following trivial example program uses getopt() to handle two program options: -n, with no associated value; and -t val, which expects an associated value.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int
main(int argc, char *argv[])
{
int flags, opt;
int nsecs, tfnd;
nsecs = 0;
tfnd = 0;
flags = 0;
while ((opt = getopt(argc, argv, "nt:")) != -1) {
switch (opt) {
case 'n':
flags = 1;
break;
case 't':
nsecs = atoi(optarg);
tfnd = 1;
break;
default: /* '?' */
fprintf(stderr, "Usage: %s [-t nsecs] [-n] name\n",
argv[0]);
exit(EXIT_FAILURE);
}
}
printf("flags=%d; tfnd=%d; nsecs=%d; optind=%d\n",
flags, tfnd, nsecs, optind);
if (optind >= argc) {
fprintf(stderr, "Expected argument after options\n");
exit(EXIT_FAILURE);
}
printf("name argument = %s\n", argv[optind]);
/* Other code omitted */
exit(EXIT_SUCCESS);
}
๐ธ SEE ALSO ๐ธ
getopt(1), getopt_long(3), getopt_long_only(3), getsubopt(3)
okay that's the whole page, you ate it, go parse some options ๐
this little rewrite was brought to you by Linux man-pages 6.20, dated 2026-02-08 โ mwah, take care bestie ๐ซถ
๐ฆ where this page comes from
- arch rolling: man-pages 6.20-1 ยท BSD-2-Clause AND BSD-3-Clause AND BSD-4.3TAHOE AND BSD-4-Clause-UC AND GPL-1.0-or-later AND GPL-2.0-only AND GPL-2.0-or-later AND GPL-3.0-or-later AND LGPL-3.0-linking-exception AND LGPL-3.0-or-later AND LicenseRef-Public-Domain AND LicenseRef-UltraPermissive AND Linux-man-pages-1-para AND Linux-man-pages-copyleft AND Linux-man-pages-copyleft-2-para AND Linux-man-pages-copyleft-var AND MIT AND Spencer-94
- nixpkgs unstable: man-pages 6.20
- ๐ the page's license: Linux-man-pages-copyleft
- Copyright 1993, Thomas Koenig <ig25@rz.uni-karlsruhe.de>
- Copyright 2006-2008, Michael Kerrisk <mtk.manpages@gmail.com>
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms