PDA

View Full Version : hướng dẫn dùng thư viện getopt.h



hardwire
07-06-2012, 01:59 PM
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
void die(const char *string){
puts(string);
exit(EXIT_FAILURE);
}
int printv(char **argv){
while(*argv){
printf("%s\n",*argv);
argv++;
}
}
const char *version="command version 1.0\nWritten by phamthechung0@gmail.com\
\ndate:7/6/2012";
const char *usage="cmd -cvh file file2";
int main(int argc,char **argv){
int ch=0;
if(argc<2) printf(usage);
while((ch=getopt(argc,argv,"cvh"))!=-1){
switch(ch){
case 'v':printf(version);exit(0);
break;
case 'h':printf("usage: cmd -cvh file.sh");exit(0);
break;
case 'c': if(argc<3) die("not enough argument");
printv(argv+2);
break;
default: puts("unknown argument");
break;
}
}
}

luc13aka47
26-10-2012, 04:34 PM
Mình bổ xung chút :D

Hàm getopt() có nhiệm vụ phân tích cú pháp các đối số command-line.
2 đối số của getopt() là argc và argv, tương ứng là số và mảng các đối số được nhập vào hàm main() khi chương trình được gọi.
Một phần tử của argv bắt đầu với '-' ( không chính xác là '-' hay '--' ) được gọi là 1 option element.
Kí tự của 1 option element ( bắt đầu từ bên phải '-' ) là những option character.
Nếu getopt() được gọi lặp, nó sẽ return những option character từ những option element.
Biến optind là chỉ số của element tiếp theo sẽ được xử lý trong argv.
Hệ thống khởi tạo biến này với giá trị 1. Caller có thể reset nó tới 1.
Nếu getopt() tìm thấy 1 option character nào khác, nó sẽ return character đó và update optind và biến static nextchar.
Nếu getopt() không tìm thấy option character nào nữa, nó return -1. optind là chỉ số của phần tử đầu tiên trong argv mà không phải là 1 option.
optstring là 1 string chứa các option character hợp lệ. Nếu 1 character như vậy được theo sau bởi 1 dấu 2 chấm, option đó yêu cầu 1 đối số, vậy nên getopt() sẽ dùng optarg để trỏ tới text của đối số đó. 2 dấu 2 chấm nghĩa là option đó yêu cầu nhận 0 hoặc 1 đối số, vậy nên optarg sẽ trỏ tới đối số đó hoặc bằng 0 nếu không có đối số nào.
Theo mặc định, getopt() sẽ thay đổi các phần tử trong argv khi nó scan. Vậy nên khi scan xong, tất cả các non-option sẽ ở cuối mảng.
Có 2 chế độ khác nữa:
• Nếu kí tự đầu tiên trong optstring là '+' hoặc biến môi trường POSIXLY_CORRECT được set, thì việc xử lý các option sẽ dừng ngay khi gặp 1 đối số non-option.
• Nếu kí tự đầu tiên trong optstring là '-', thì mỗi element non-option trpng argv sẽ được xử lý như là 1 đối số của 1 option với character code 1.
Nếu getopt() tìm thấy 1 option character không hợp lệ, nó sẽ in 1 thông báo lỗi tới stderr, lưu kí tự đó tới optopt và return '?'. Caller có thể chặn thông báo lỗi bằng việc set opterr = 0.

Ngoài getopt(), còn có hàm getopt_long() cũng tương tự như getopt(), getopt_long() cũng xử lý cả long option, nhưng long option của mà nó nhận phải bắt đầu với 2 dấu gach ngang "--".

Một ví dụ đơn giản sử dụng getopt_long() :



#include <stdio.h> /* for printf */
#include <stdlib.h> /* for exit */
#include <getopt.h>


int main(int argc, char **argv)
{
int c;
int digit_optind = 0;

while (1)
{
int this_option_optind = optind ? optind : 1;
// chí số option trong mảng long_option
int option_index = 0;
// mảng long_option
static struct option long_options[] =
{
{"add", required_argument, 0, 0 },
{"append", no_argument, 0, 0 },
{"delete", required_argument, 0, 0 },
{"verbose", no_argument, 0, 0 },
{"create", required_argument, 0, 'c'},
{"file", required_argument, 0, 0 },
{0, 0, 0, 0 }

};

c = getopt_long(argc, argv, "abc:d:012", long_options, &option_index);
// nếu không tìm thấy option nào
if (c == -1)
break;

switch (c)
{
case 0:
// in ra tên option đang xử lý
printf("option %s", long_options[option_index].name);
// in ra đối số đi kèm option
if (optarg)
printf(" with arg %s", optarg);
printf("\n");
break;

case '0':
case '1':
case '2':
if (digit_optind != 0 && digit_optind != this_option_optind)
printf("digits occur in two different argv-elements.\n");
digit_optind = this_option_optind;
printf("option %c\n", c);
break;

case 'a':
printf("option a\n");
break;

case 'b':
printf("option b\n");
break;

case 'c':
printf("option c with value '%s'\n", optarg);
break;

case 'd':
printf("option d with value '%s'\n", optarg);
break;

case '?':
break;

default:
printf("?? getopt returned character code 0%o ??\n", c);
}
}

if (optind < argc) {
printf("non-option ARGV-elements: ");
while (optind < argc)
printf("%s ", argv[optind++]);
printf("\n");
}

exit(EXIT_SUCCESS);
}

hardwire
01-02-2013, 05:30 PM
sao hàm getopt_long phải nằm trong while(1)

luc13aka47
01-02-2013, 06:00 PM
The getopt() function parses the command-line arguments. Its arguments argc and argv are the argument count and array as passed to the main() function on program invocation. An element of argv that starts with '-' (and is not exactly "-" or "--") is an option element. The characters of this element (aside from the initial '-') are option characters. If getopt() is called repeatedly, it returns successively each of the option characters from each of the option elements.
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 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() and getopt_long_only() also 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 an extraneous parameter.



http://linux.die.net/man/3/getopt_long

Hiểu đơn giản :

argc sẽ chứa số đối số.
argv là mảng các đối số.

Mỗi phần tử của argv bắt đầu với '-' được gọi là 1 'option element'.
Các kí tự bên phải '-' hoặc '--' của mỗi 'option element' được gọi là 'option characters'. ( với getopt_long() , gặp 'option element' bắt đầu với '--' thì chuyển nó về short option tương ứng để xử lý ).

Nếu gọi lặp getopt_long(), thì nó sẽ return lần lượt từng 'option characters' của mỗi 'option element' trong argv, dưới dạng short option ( tức là khi gặp '--' là long option thì nó chuyển về short option như đã nói ở trên ). Khi hết thì return -1.