Một cách tiếp cận là mã hóa std::string
thành một std::vector<std::string>
, sau đó chuyển kết quả đến Boost.ProgramOption's command_line_parser
. Số documentation của Boost.ProgramOption sẽ trình bày ngắn gọn cách tiếp cận này. Ngoài ra, tôi sử dụng cách tiếp cận tương tự như một phần của câu trả lời this.
Đây là một hoàn dụ tối thiểu:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <string>
#include <vector>
#include <boost/bind.hpp>
#include <boost/program_options.hpp>
#include <boost/tokenizer.hpp>
// copy_if was left out of the C++03 standard, so mimic the C++11
// behavior to support all predicate types. The alternative is to
// use remove_copy_if, but it only works for adaptable functors.
template <typename InputIterator,
typename OutputIterator,
typename Predicate>
OutputIterator
copy_if(InputIterator first,
InputIterator last,
OutputIterator result,
Predicate pred)
{
while(first != last)
{
if(pred(*first))
*result++ = *first;
++first;
}
return result;
}
/// @brief Tokenize a string. The tokens will be separated by each non-quoted
/// space or equal character. Empty tokens are removed.
///
/// @param input The string to tokenize.
///
/// @return Vector of tokens.
std::vector<std::string> tokenize(const std::string& input)
{
typedef boost::escaped_list_separator<char> separator_type;
separator_type separator("\\", // The escape characters.
"= ", // The separator characters.
"\"\'"); // The quote characters.
// Tokenize the intput.
boost::tokenizer<separator_type> tokens(input, separator);
// Copy non-empty tokens from the tokenizer into the result.
std::vector<std::string> result;
copy_if(tokens.begin(), tokens.end(), std::back_inserter(result),
!boost::bind(&std::string::empty, _1));
return result;
}
int main()
{
// Variables that will store parsed values.
std::string address;
unsigned int port;
// Setup options.
namespace po = boost::program_options;
po::options_description desc("Options");
desc.add_options()
("address", po::value<std::string>(&address))
("port", po::value<unsigned int>(&port))
;
// Mock up input.
std::string input = "--address 127.0.0.1 --port 12345";
// Parse mocked up input.
po::variables_map vm;
po::store(po::command_line_parser(tokenize(input))
.options(desc).run(), vm);
po::notify(vm);
// Output.
std::cout << "address = " << address << "\n"
"port = " << port << std::endl;
}
nào xuất ra như sau:
address = 127.0.0.1
port = 12345
Nguồn
2013-08-22 16:06:04
lý do tại sao bạn sẽ vượt qua một chuỗi? bạn nhận được các tùy chọn như char ** đã có trong chương trình C++ của bạn? – codeling
Tôi sử dụng ổ cắm UNIX (asio :: local) để truyền xung quanh chuỗi std ::. Bây giờ tôi muốn phân tích chuỗi này bằng cách sử dụng các tùy chọn chương trình. Vấn đề là ví dụ chỉ bao gồm po :: parse_command_line (ac, av, desc), nhưng tôi không có av. Tôi có một chuỗi hoàn chỉnh chứa các đối số. – Darneas
@codeling Vì tôi đang viết một bài kiểm tra đơn vị. – Eyal