2013-08-06 25 views
10

Tôi đang tạo một chương trình nhỏ trong C có giao dịch với nhiều đối số dòng lệnh, vì vậy tôi quyết định sử dụng getopt để sắp xếp chúng cho tôi. Tuy nhiên, tôi muốn hai đối số không bắt buộc (tệp nguồn và đích) là bắt buộc, vì vậy bạn phải có chúng làm đối số trong khi gọi chương trình, ngay cả khi không có cờ hoặc đối số khác.Sử dụng getopt trong C với các đối số không tùy chọn

Dưới đây là một phiên bản đơn giản của những gì tôi phải xử lý các đối số với cờ:

while ((c = getopt(argc, argv, "i:d:btw:h:s:")) != -1) { 
    switch (c) { 
     case 'i': { 
      i = (int)atol(optarg); 
     } 
     case 'd': { 
      d = (int)atol(optarg); 
     } 
     case 'b': 
      buf = 1; 
      break; 
     case 't': 
      time = 1; 
      break; 
     case 'w': 
      w = (int)atol(optarg); 
      break; 
     case 'h': 
      h = (int)atol(optarg); 
      break; 
     case 's': 
      s = (int)atol(optarg); 
      break; 
     default: 
      break; 
    } 
} 

Làm thế nào để chỉnh sửa này để lập luận phi tùy chọn cũng được xử lý?

Tôi cũng muốn có thể có các tùy chọn không phải trước hoặc sau các tùy chọn, vậy cách xử lý sẽ như thế nào?

Trả lời

13

getopt đặt biến số optind để cho biết vị trí của đối số tiếp theo.

thêm mã tương tự như sau sau các tùy chọn loop:

if (argv[optind] == NULL || argv[optind + 1] == NULL) { 
    printf("Mandatory argument(s) missing\n"); 
    exit(1); 
} 

Edit:

Nếu bạn muốn cho phép tùy chọn sau khi tranh luận thường xuyên, bạn có thể làm điều gì đó tương tự như sau:

while (optind < argc) { 
    if ((c = getopt(argc, argv, "i:d:btw:h:s:")) != -1) { 
    // Option argument 
    switch (c) { 
     case 'i': { 
      i = (int)atol(optarg); 
     } 
     case 'd': { 
      d = (int)atol(optarg); 
     } 
     case 'b': 
      buf = 1; 
      break; 
     case 't': 
      time = 1; 
      break; 
     case 'w': 
      w = (int)atol(optarg); 
      break; 
     case 'h': 
      h = (int)atol(optarg); 
      break; 
     case 's': 
      s = (int)atol(optarg); 
      break; 
     default: 
      break; 
    } 
    else { 
     // Regular argument 
     <code to handle the argument> 
     optind++; // Skip to the next argument 
    } 
} 
+1

OK, nhưng vòng lặp của tôi sẽ xuất hiện nếu các đối số bắt buộc trước các đối số bắt buộc, vì vậy chỉ có các đối số bắt buộc sẽ được xử lý chứ không phải tùy chọn bắt buộc. Làm thế nào để tôi sửa lỗi này? –

+1

Nó là phổ biến để yêu cầu các tùy chọn đến trước khi lập luận. Chỉ cần xác định nó trong trang 'man'. –

+2

Vâng, tôi biết nhưng ví dụ với lệnh ssh, cờ -p có thể đến trước * hoặc * sau tên người dùng bắt buộc @ server. Tôi chỉ muốn biết làm thế nào để làm điều đó –

4

Ví dụ thực sự tốt có thể được tìm thấy tại đây: GNU Libc Mã:

#include <ctype.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 

int 
main (int argc, char **argv) 
{ 
int aflag = 0; 
int bflag = 0; 
char *cvalue = NULL; 
int index; 
int c; 

opterr = 0; 

while ((c = getopt (argc, argv, "abc:")) != -1) 
switch (c) 
{ 
case 'a': 
    aflag = 1; 
    break; 
case 'b': 
    bflag = 1; 
    break; 
case 'c': 
    cvalue = optarg; 
    break; 
case '?': 
    if (optopt == 'c') 
    fprintf (stderr, "Option -%c requires an argument.\n", optopt); 
    else if (isprint (optopt)) 
    fprintf (stderr, "Unknown option `-%c'.\n", optopt); 
    else 
    fprintf (stderr, 
     "Unknown option character `\\x%x'.\n", 
     optopt); 
    return 1; 
default: 
    abort(); 
} 

printf ("aflag = %d, bflag = %d, cvalue = %s\n", 
    aflag, bflag, cvalue); 

for (index = optind; index < argc; index++) 
printf ("Non-option argument %s\n", argv[index]); 
return 0; 
} 

Nó cho phép có các tùy chọn trước và sau đối số. Tôi đã biên dịch và chạy ví dụ kiểm tra:

$ ./a.out aa ff bb -a -ctestparam hello 
aflag = 1, bflag = 0, cvalue = testparam 
Non-option argument aa 
Non-option argument ff 
Non-option argument bb 
Non-option argument hello 
Các vấn đề liên quan