2009-11-26 3 views
12

Tôi đang sử dụng boost :: program_options library để xử lý tham số dòng lệnh. Tôi cần chấp nhận tên tệp qua tùy chọn -r, trong trường hợp nếu nó trống (-r được cung cấp không có tham số), tôi cần sử dụng stdin.Làm thế nào để chấp nhận giá trị rỗng trong boost :: program_options

desc.add_options() 
("replay,r", boost::program_options::value<std::string>(), "bla bla bla") 

Trong trường hợp này, quảng cáo sẽ không chấp nhận -r không có thông số và ném ngoại lệ. tùy chọn default_value() không hoạt động tốt vì nó sẽ làm cho giá trị trả về của thư viện ngay cả khi người dùng không đưa ra tùy chọn -r.

Bất kỳ ý tưởng nào về cách làm việc xung quanh?

Trả lời

26

Vui lòng sử dụng các phương pháp implicit_value, ví dụ

desc.add_options() 
("replay,r", po::value<std::string>()->implicit_value("stdin"), "bla bla bla") 

Điều này làm cho sự lựa chọn chấp nhận hoặc là 0 hoặc 1 thẻ, và nếu không có thẻ được cung cấp, nó sẽ hoạt động như thể 'stdin' được cung cấp. Tất nhiên, bạn có thể chọn bất kỳ giá trị tiềm ẩn nào khác - bao gồm chuỗi rỗng và '-' theo đề xuất của mch.

+0

Cảm ơn bạn! Hoạt động hoàn hảo – cppalex

+0

@Vladimir Prus, đây là một câu hỏi khác về các tùy chọn không có giá trị tại đây http://stackoverflow.com/questions/7174781/boost-program-options-notifier-for-options-with-no-value Tôi muốn có thể thêm bộ thông báo cho các tùy chọn đó hoặc viết một bản vá để bật nó. Xin vui lòng, bình luận, cảm ơn. – Riga

+0

Thật không may, điều này không hoạt động khi một giá trị rỗng được đưa ra trong tập tin INI, vì một lý do nào đó. –

1

Tôi không nghĩ rằng bất kỳ thư viện phân tích cú pháp dòng lệnh nào đều cho phép bạn có các tùy chọn có thể đưa ra một đối số hay không. Nếu một tùy chọn yêu cầu một đối số, bạn phải cung cấp một đối số. Trong trường hợp này, thực hành tiêu chuẩn (trong * NIX anyway) là sử dụng '-' làm tên tệp để biểu thị rằng bạn muốn đọc từ đầu vào tiêu chuẩn.

+0

Boost :: program_options * does * cho phép điều này thông qua zero_tokens(). – Rhubbarb

5

Bạn có thể thử một thủ thuật với các tùy chọn multitokenzero_tokens:

using namespace std; 
namespace po = boost::program_options; 

vector<string> replay; 

po::options_description desc("Allowed options"); 
desc.add_options() 
    ("replay,r", po::value< vector<string> >(&replay)->multitoken()->zero_tokens(), "bla bla bla"); 

po::variables_map vm;   
po::store(po::parse_command_line(argc, argv, desc), vm); 
po::notify(vm);  

if (vm.count("replay")) 
{ 
    size_t s = vm["replay"].as< vector<string> >().size(); 
    if (s == 0) 
    cout << "replay without args" << endl; 
    else if (s == 1) 
    cout << "replay with one arg" << endl; 
    else 
    cout << "replay with multiple args" << endl; 
} 
else 
    cout << "replay not specified" << endl; 

Sau đó chỉ cần đếm số lượng các yếu tố trong replay vector. Bạn sẽ muốn báo lỗi nếu nhiều đối số được chuyển đến tùy chọn phát lại .