-g, -o-o test 中的 test#include <unistd.h>
extern char *optarg; // 選項參數指針
extern int optind; // 下一個 argv 索引
extern int optopt; // 最後一個已知選項
extern int opterr; // 是否打印錯誤信息 (默認 1)
extern int optreset; // 重置狀態 (BSD/GNU 擴展)
int getopt(int argc, char *const argv[], const char *optstring);
| 格式 | 含義 | 示例 |
|---|---|---|
x | 選項 -x 無參數 | "ab" → -a -b |
x: | 選項 -x 必須有參數 | "o:" → -o file |
x:: | 選項 -x 參數可選 (GNU 擴展) | "v::" → -v 或 -vlevel |
int aflag=0, bflag=0, cflag=0;
int ch;
while ((ch = getopt(argc, argv, "ab:c")) != -1) {
switch (ch) {
case 'a': aflag=1; break;
case 'b': bflag=1; printf("arg: %s\n", optarg); break;
case 'c': cflag=1; break;
case '?': fprintf(stderr, "Unknown: %c\n", optopt); break;
}
}
// 剩餘非選項參數
for (; optind < argc; ++optind) process(argv[optind]);
opterr = 0 禁用默認錯誤輸出。optstring 首字符為 : (如 ":ab:c"):'?', optopt 存字符。':' (而非 '?'),可精確區分。#include <getopt.h>
struct option {
const char *name; // 長選項名 (無 --)
int has_arg; // no_argument(0), required_argument(1), optional_argument(2)
int *flag; // 非 NULL 時設置 *flag=val, 返回 0
int val; // flag==NULL 時返回此值
};
int getopt_long(int argc, char *const argv[], const char *optstring,
const struct option *longopts, int *longindex);
static struct option longopts[] = {
{"help", no_argument, 0, 'h'},
{"output", required_argument, 0, 'o'},
{"verbose", optional_argument, 0, 'v'},
{0, 0, 0, 0} // 必須以全 0 結尾
};
調用:getopt_long(argc, argv, "ho:v::", longopts, NULL)
--help 等價 -h,--output=file 或 --output file 等價 -o file。
#include <stdio.h>
#include <unistd.h>
#include <getopt.h>
int main(int argc, char *argv[]) {
static struct option opts[] = {
{"help", 0, 0, 'h'},
{"input", 1, 0, 'i'},
{"output", 1, 0, 'o'},
{"verbose", 2, 0, 'v'},
{0,0,0,0}
};
int c, vlevel = 0;
char *in = NULL, *out = NULL;
while ((c = getopt_long(argc, argv, "hi:o:v::", opts, NULL)) != -1) {
switch (c) {
case 'h': puts("Usage: ..."); return 0;
case 'i': in = optarg; break;
case 'o': out = optarg; break;
case 'v': vlevel = optarg ? atoi(optarg) : 1; break;
case '?': return 1;
}
}
// 處理 in/out/vlevel...
return 0;
}
getopt 會重排 argv (將選項移前),若需保留原序,先複製。optreset = 1; optind = 1; (BSD) 或重新構造 argv (Linux)。-- 強制結束選項解析,後續視為非選項參數。getopt 使用全局靜態狀態,非線程安全。多線程請用 getopt_r (GNU) 或自行加鎖。getopt/getopt_long 是 POSIX 標準、零依賴、輕量級的命令行解析利器。掌握 optstring 語法、長選項結構體、錯誤處理模式與 optind 後續參數遍歷,即可編寫專業級 CLI 工具。