تابع کتابخانهای getopt(3) آرگومانهای خط فرمان را parse میکند.
#include <unistd.h>
int getopt(int argc, char *argv[], const char *optstring);
returns next option character on success,
-1 if all command-line options have been parsed,
? if option character is not in optstring,
? (or :) if required argument is not provided.
المانی که در خط فرمان باشد و با - شروع شده باشد و دقیقا - و -- نباشد یک option است. کاراکتری که دقیقا بعد از - میآید کاراکتر optioin نامیده میشود. اگر تابع getopt را به صورت متوالی فراخوانی کنیم در هر بار کاراکتر option بعدی را باز میگرداند.
optind ایندکس عنصر بعدی در آرایهی argv است که باید پردازش شود. سیستم آن را با ۱ مقداردهی اولیه میکند و ما میتوانیم بعدا نیز به آن مقدار ۱ بدهیم تا آرایهی آرگومانهای خط فرمان یا هر آرایهی دیگری را از نو پردازش کنیم.
کاراکتر option نباید - و : , ; باشد.
اگر بعد از کاراکتر آپشن : باشد آن option نیاز به یک آرگومان بعد از خود دارد. :: میگوید که آرگومان این کاراکتر آپشن اختیاری است.
اگر آرگومان کاراکتر آپشن اجباری باشد یعنی بعد از کاراکتر آپشن فقط یک: آمده باشد در این صورت آرگومان هم میتواند به کاراکتر آپشن بچسبد و هم اینکه با space از کاراکتر آپشن جدا شده باشد.
getopt(argc, argv, "c:")
$ program_name -csalam
$ program_name -c salam
با این کد موضوع را بررسی کنید.
اما اگر کاراکتر آپشن با :: درخواست یک آرگومان اختیاری کند در این صورت در خط فرمان آرگومان باید به کاراکتر آپشن بچسبد. در غیر این صورت optarg با NULL پر میشود.
getopt(argc, argv, "c::");
$ program_name -csalam # correct
$ program_name -c salam # incorrect
با کد داده شده این موضوع را بررسی کنید.
در مورد W در optstring مطالعه شود و مثال getopt3.c تکمیل گردد.
آرگومانهای خط فرمان به شکل سفت و سخت پردازش میشوند به این معنی که اگر یک آپشن نیاز به یک آرگومان اجباری داشته باشد، آرگومان بعدی را مصرف میکند فارغ از این که آرگومان بعدی واقعا آرگومانی است که برای آن آپشن فراهم شده است یا اینکه آپشن بعدی است (در این صورت کاربر در فراهم کردن اطلاعات اشتباه کرده است.)
در هنگام پردازش آپشنهای موجود در خط فرمان با دو نوع خطا ممکن است مواجه شویم:
به طور کلی getopt(3) این نوع خطاها را به صورت زیر مدیریت میکند:
optopt مینویسد و به عنوان نتیجهی تابع کاراکتر ? را برمیگرداند.opterr به صفر میتوانیم چاپ اتوماتیک پیغام خطا در خروجی استاندارد را غیر فعال کنیم. در این صورت وقوع خطا را میتوان از خروجی تابع ()getopt تشخیص داد.اگر اول optstring (در صورت وجود + و − بعد از آنها) : بذاریم اولا بدون opterr=0 چاپ خطا در خروجی استاندارد سرکوب میشود و دوما در صورت نبودن آرگومان اجباری برای یک کاراکتر آپشن تابع به جای ? مقدار : را برمیگرداند. در این صورت به راحتی میتوانیم بین دو نوع خطا تمیز دهیم.
موارد فوق را با این مثال بررسی کنید.
به صورت پیشفرض تابع ()getopt ترتیب عناصر آرایهی argv را تغییر میدهد. لذا سرانجام تمام المانهایی که آپشن نیستند در انتهای آرایه قرار میگیرند.
این موضوع را با این مثال و با دستور زیر تست کنید:
$ ./a.out -a -b man -c -e -d
این رفتار را به دو صورت میتوان تغییر داد:
+ باشد یا متغیر محیطی POSIXLY_CORRECT ست شده باشد در این صورت تابع getopt به محض روبرو شدن با اولین آرگومانی که آپشن نیست متوقف میشود. مثال فوق را با این دو مورد بررسی کرده و نتیجه را ببینید.+ اولین کاراکتر optstring نباشد به عنوان یک کاراکتر آپشن معمولی لحاظ خواهد شد. مثال.+ خواهد بود. اولی به معنای POSIXLY_CORRECT و دومی که در میانه یا انتهای optstring است به عنوان کاراکتر آپشن خواهد بود.- باشد در این صورت تمامی المانهای غیر آپشن آرایهی argv به عنوان آرگومان آپشن کاراکتر با کد ۱ منظور خواهد شد. مثالآرگومان مخصوص -- در خط فرمان به معنای پایان اسکن کردن آپشنها فارغ از هر نوع مد اسکن کردن (موارد ۱ و ۲) است.
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 was not in optstring, then '?' is returned. If getopt() encounters an option with a missing argument, then the return value depends on the first character in optstring: if it is ':', then ':' is returned; otherwise '?' is returned.
منوال تابع کتابخانهای getopt_long(3)
تابع (3)getopt_long مثل (3)getopt عمل میکند با این تفاوت که این تابع علاوه بر آپشنهای کوتاه، آپشنهای طولانی نیز میپذیرد که با -- شروع میشوند.
اگر برنامه فقط آپشنهای طولانی میپذیرد و آپشنهای کوتاه را پشتیبانی نمیکند باید optstring را رشتهی خالی یعنی "" قرار داد و نه NULL.
آپشنهای طولانی پارامترهای مورد نیاز خود را در خط فرمان به صورت --arg=param یا --arg param میپذیرند.
#include <getopt.h>
struct option {
const char *name, /* the name of the long option */
int has_arg; /* no_argument|required_argument|optional_argument */
int *flag;
int val; /* is the value to return, or to load into
the variable pointed to by flag */
};
int getopt_long(int argc, char *argv[], const char *optstring,
const struct option *longopts, int *longindex);
int getopt_long_only(int argc, char *argv[], const char *optstring,
const struct option *longopts, int *longindex);
در تابع (3)getopt_long مانند تابع (3)getopt دسترسی کامل به متغیرهای optind و optarg داریم.
منوال تابع کتابخانهای getopt_long_only(3)
تابع getopt_long_only(3) دقیقا مانند getopt_long(3) است با این تفاوت که - مانند -- میتواند یک آپشن طولانی را مشخص کند. به این صورت که آپشن وارد شده با - ابتدا در لیست آپشنهای طولانی جستجو میشود و اگر یافت نشود در ادامه لیست آپشنهای کوتاه نیز جستجو میشود.
getopt_long() and getopt_long_only() return the option character when a short option is recognized. For a long option, they return val if flag is NULL, and 0 otherwise. Error and -1 returns are the same as for getopt(), plus '?' for an ambiguous match or extraneous parameter.