Friday, July 31, 2015

Một chương trình C/C++ sẽ bắt đầu với hàm main và các đối số được truyền từ môi trường ngoài vào.

args.c

 #include <stdio.h>  
 #include <stdlib.h>  
 int main(int argc, char **argv)  
 {  
   int arg;  
   
   printf("Program name: %s \n", argv[0]);  
   for(arg = 1; arg < argc; arg++) {  
       printf("argument %d: %s\n", arg, argv[arg]);  
   }  
   
   return 0;  
 }   

+ argc
Số tham số được truyền vào cho hàm main, argc >= 1 bởi vì mặc định luôn có ít nhất một đối số được truyền vào đó là tên của chính chương trình đó được lưu trong argv[0].
+ argv
Mảng chứa các tham số truyền vào cho hàm main. argv[0] là tên của chương trình; argv[1], argv[2], ... lần lượt là các tham số của người dùng truyền vào.

Compile & Execute:
 $ gcc args.c   
 $ ./a.out par1 par2  
 Program name: ./a.out   
 argument 1: par1  
 argument 2: par2  
   

Unix/Linux cung cấp thêm các hàm dưới đây để truyền các đối số phức tạp hơn.

1. getopt
 #include <unistd.h>  
 int getopt(int argc, char *const argv[], const char *optstring);  
 extern char *optarg;  
 extern int optind, opterr, optopt;  

+ argc
Số các đối số, được lấy từ argc của hàm main.
+ argv
Mảng các đối số, được lấy từ argv của hàm main
+ optstring
Các option để phân tích các đối số từ mảng mảng argv. Khi truyền trước các option phải có dấu trừ '-'. Trong trường hợp phía sau option là dấu hai chấm ':' thì option đó phải có giá trị đối số đi kèm, và nó sẽ được lưu trong optarg.

Ex:
 getopt(argc, argv,"apl:b:")  
tương ứng với -a, -p, -l value1, -b value2.

+ return
    - Trả về các option truyền từ ngoài vào mà nó trùng với một trong những option được liệt trong optstring, nếu có giá trị đi kèm option thì được lưu ở biến optarg
    - Trả về ':' nếu có option trùng với một trong những option trong optstring và option đó bắt buộc phải có giá trị đi kèm, tuy nhiên lúc này nó lại không có giá trị đi kèm
    - Trả về '?' nếu không có option trùng, biến optopt lưu option không trùng đó
    - Trả về -1 nếu không còn option nào để phân tích (kết thúc quá trình phân tích)

+ optind
Số thứ tự các đối số truyền vào argv[optind]

Ex:
getopt.c
 #include <stdio.h>  
 #include <unistd.h>  
 #include <stdlib.h>  
   
 /*  
  *  
  * ./a.out -i -lr 'hi there' -f fred.c -q  
  *  
  * */  
 int main(int argc, char *argv[])  
 {  
   int opt;  
   while((opt = getopt(argc, argv, ":if:lr")) != -1) {  
     switch(opt) {  
     case 'i':  
     case 'l':  
     case 'r':  
       printf("option: %c\n", opt);  
       break;  
     case 'f':  
       printf("filename: %s\n", optarg);  
       break;  
     case ':':  
       printf("option needs a value\n");  
       break;  
     case '?':  
       printf("unknown option: %c\n", optopt);  
       break;  
     }  
   }  
   for(; optind < argc; optind++)  
     printf("argument: %s\n", argv[optind]);  
   exit(0);  
 }  
   

Compile & Execute:
 $ gcc getopt.c  
 $ ./a.out -i  
 option: i  
 $   
 $ ./a.out -i 5  
 option: i  
 argument: 5  
 $   
 $   
 $ ./a.out -f  
 option needs a value  
 $   
 $ ./a.out -f fread.c  
 filename: fread.c  
 $   
 $ ./a.out -q  
 unknown option: q  
 $   
 $   
 $ ./a.out -lr  
 option: l  
 option: r  
 $   
 $ ./a.out -i -lr 'hi there' -f fred.c -q  
 option: i  
 option: l  
 option: r  
 filename: fred.c  
 unknown option: q  
 argument: hi there  
   

Ex2:
getopt2.c
 #include <unistd.h>  
 #include <stdio.h>  
 #include <stdlib.h>  
 #include <getopt.h>  
   
 /** Program to calculate the area and perimeter of   
  * a rectangle using command line arguments  
  */  
 void print_usage() {  
   printf("Usage: rectangle [ap] -l num -b num\n");  
 }  
   
 int main(int argc, char *argv[]) {  
   int option = 0;  
   int area = -1, perimeter = -1, breadth = -1, length =-1;  
   
   //Specifying the expected options  
   //The two options l and b expect numbers as argument  
   while ((option = getopt(argc, argv,"apl:b:")) != -1) {  
     switch (option) {  
        case 'a' : area = 0;  
          break;  
        case 'p' : perimeter = 0;  
          break;  
        case 'l' : length = atoi(optarg);   
          break;  
        case 'b' : breadth = atoi(optarg);  
          break;  
        default: print_usage();   
          exit(EXIT_FAILURE);  
     }  
   }  
   if (length == -1 || breadth ==-1) {  
     print_usage();  
     exit(EXIT_FAILURE);  
   }  
   
   // Calculate the area  
   if (area == 0) {  
     area = length * breadth;  
     printf("Area: %d\n",area);  
   }  
   
   // Calculate the perimeter  
   if (perimeter == 0) {  
     perimeter = 2 * (length + breadth);  
     printf("Perimeter: %d\n",perimeter);  
   }  
   return 0;  
 }  

2. getopt_long

 struct option {  
   const char *name;  
   int has_arg;  
   int *flag;  
   int val;  
 };  

Option Member Description
name The name of the long option. Abbreviations will be accepted as longas they cannot be confused with other options.
has_arg Whether this option takes an argument. Set to 0 for options that donot take an argument, 1 for options that must have a value, and 2 forthose that have an optional argument.
flag Set to NULL to have getopt_long return the value given in val whenthis option is found. Otherwise, getopt_long returns 0 and writesthe value of val into the variable pointed to by flag .
val The value getopt_long is to return for this option.


Ex:
getopt_long.c
 #include <stdio.h>  
 #include <unistd.h>  
 #include <stdlib.h>  
   
 #define _GNU_SOURCE  
 #include <getopt.h>  
   
 /*  
  *  
  * ./longopt --init –l --file=fred.c 'hi there'  
  *  
  * */  
 int main(int argc, char *argv[])  
 {  
   int opt;  
   struct option longopts[] = {  
   {"initialize", 0, NULL, 'i'},  
   {"file", 1, NULL, 'f'},  
   {"list", 0, NULL, 'l'},  
   {"restart", 0, NULL, 'r'},  
   {0,0,0,0}};  
   while((opt = getopt_long(argc, argv, ":if:lr", longopts, NULL)) != -1) {  
     switch(opt) {  
     case 'i':  
     case 'l':  
     case 'r':  
       printf("option: %c\n", opt);  
       break;  
     case 'f':  
       printf("filename: %s\n", optarg);  
       break;  
     case ':':  
       printf("option needs a value\n");  
       break;  
     case '?':  
       printf("unknown option: %c\n", optopt);  
       break;  
     }  
   }  
   for(; optind < argc; optind++)  
     printf("argument: %s\n", argv[optind]);  
   exit(0);  
 }  
   

Execute:
 $ ./longopt --init –l --file=fred.c ‘hi there’  
 option: i  
 option: l  
 filename: fred.c  
 argument: hi there  

Leave a Reply

Subscribe to Posts | Subscribe to Comments

- Copyright © Lập trình hệ thống nhúng Linux . Powered by Luong Duy Ninh -