英文:
C++ splitting args by space, but dont split values with spaces
问题
我有一个命令行参数,格式如下字符串
"-opt1 val1 -opt2 val1 val2 -opt3 val3"
当我使用 boost 按空格拆分时,结果将如下
boost::split(target_vector, inputString, boost::is_any_of(" "), boost::token_compress_on);
["-opt1", "val1", "-opt2", "val1", "val2", "-opt3", "val3"]
我更希望结果是
["-opt1", "val1", "-opt2", "val1 val2", "-opt3", "val3"]
我可以编写一些逻辑来处理遇到的 -,但想知道是否有内置的方法来做到这一点。
英文:
I have a command line argument as following string
"-opt1 val1 -opt2 val1 val2 -opt3 val3"
When I use boost split by space, result will be following
boost::split(target_vector, inputString, boost::is_any_of(" "), boost::token_compress_on);
["-opt1", "val1", "-opt2", "val1", "val2", "-opt3", "val3"]
I would rather like result to be
["-opt1", "val1", "-opt2", "val1 val2", "-opt3", "val3"]
I can write some logic around encountering - but wanted to see if theer was some built in way to do it.
答案1
得分: 1
以下是翻译好的部分:
使用通用字符串拆分函数(分词器),可以将字符串拆分为以下输出:
option : opt1 val1
option name = opt1
- value : val1
option : opt2 val1 val2
option name = opt2
- value : val1 val2
option : opt3 val3
option name = opt3
- value : val3
以下是源代码:
#include <iostream>
#include <limits>
#include <vector>
#include <string_view>
// 通用字符串拆分算法(分词器)
// 使用字符串视图以避免涉及字符串副本。
auto split(std::string_view string, std::string_view delimiters, std::size_t maximum_number_of_substrings = std::numeric_limits<std::size_t>::max())
{
std::vector<std::string_view> substrings;
if (string.size() == 0ul)
{
return substrings;
}
if (delimiters.size() == 0ul)
{
substrings.emplace_back(string);
return substrings;
}
auto start_pos = string.find_first_not_of(delimiters);
auto end_pos = start_pos;
auto max_length = string.length();
while (start_pos < max_length)
{
maximum_number_of_substrings--;
if (maximum_number_of_substrings != 0ul)
{
end_pos = std::min(max_length, string.find_first_of(delimiters, start_pos));
}
else
{
end_pos = max_length;
}
if (end_pos != start_pos)
{
substrings.emplace_back(&string[start_pos], end_pos - start_pos);
start_pos = string.find_first_not_of(delimiters, end_pos);
}
}
return substrings;
}
int main()
{
// 演示命令行
// 注意,我现在不检查输入字符串的有效性
// 这只是一种快速的方法示意。
std::string command_line{ "-opt1 val1 -opt2 val1 val2 -opt3 val3" };
// 首先根据“-”拆分创建字符串视图向量
auto options = split(command_line, "-");
// 然后可以通过空格“ ”拆分每个拆分的子字符串
for (const auto& option : options)
{
std::cout << "option : " << option << "\n";
auto values = split(option, " ", 2ul);
// 第一个拆分值将是选项名称
std::cout << " option name = " << values[0] << "\n";
// 其他子字符串将是值
for (std::size_t n{ 1ul }; n < values.size(); ++n)
{
std::cout << " - value : " << values[n] << "\n";
}
}
return 0;
}
希望这对你有所帮助。
英文:
With a generic string split function (tokenizer) the string can be split to generate output like this :
option : opt1 val1
option name = opt1
- value : val1
option : opt2 val1 val2
option name = opt2
- value : val1 val2
option : opt3 val3
option name = opt3
- value : val3
Here is the source code:
#include <iostream>
#include <limits>
#include <vector>
#include <string_view>
// a generic string splitting algorithm (tokenizer)
// string_views are used so there will be no string copies involved.
auto split(std::string_view string, std::string_view delimiters, std::size_t maximum_number_of_substrings = std::numeric_limits<std::size_t>::max())
{
std::vector<std::string_view> substrings;
if (string.size() == 0ul)
{
return substrings;
}
if (delimiters.size() == 0ul)
{
substrings.emplace_back(string);
return substrings;
}
auto start_pos = string.find_first_not_of(delimiters);
auto end_pos = start_pos;
auto max_length = string.length();
while (start_pos < max_length)
{
maximum_number_of_substrings--;
if (maximum_number_of_substrings != 0ul)
{
end_pos = std::min(max_length, string.find_first_of(delimiters, start_pos));
}
else
{
end_pos = max_length;
}
if (end_pos != start_pos)
{
substrings.emplace_back(&string[start_pos], end_pos - start_pos);
start_pos = string.find_first_not_of(delimiters, end_pos);
}
}
return substrings;
}
int main()
{
// demo command line
// note I do NOT check for validity of the input string right now
// this is a quick sketch of the approach.
std::string command_line{ "-opt1 val1 -opt2 val1 val2 -opt3 val3" };
// first create a vector of string_views based on splitting by "-"
auto options = split(command_line, "-");
// then each of those split substrings can be split by a space " "
for (const auto& option : options)
{
std::cout << "option : " << option << "\n";
auto values = split(option, " ", 2ul);
// the first split value will be the option name
std::cout << " option name = " << values[0] << "\n";
// the other substrings will be the values
for (std::size_t n{ 1ul }; n < values.size(); ++n)
{
std::cout << " - value : " << values[n] << "\n";
}
}
return 0;
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论