文章目录
- 前言
- 一、如何实现?
- 1、实现split
- 2、split双引号
- 3、奇数下标元素加入结果
- 4、偶数下标元素split空格
- 二、完整代码
- 三、使用示例
- 1、解析命令行
- 2、构造argc、argv
- 总结
前言
一般开启子进程的时候,需要传参数,通常直接传输命令行字符串,进入main会自动转换为argc、argv的形式。有些时候会需要需要自己解析命令行的情况,通常采用split空格就可以了,但如果需要支持双引号则会麻烦一些。
一、如何实现?
1、实现split
实现一个简单的split
#include <iostream>
#include <sstream>
#include <vector>
#include <string>
static std::vector<std::string> split(const std::string &str, char delim)
{
std::vector<std::string> tokens;
std::istringstream iss(str);
std::string token;
while (std::getline(iss, token, delim))
if (!token.empty())
tokens.push_back(token);
return tokens;
}
2、split双引号
根据双引号进行分割。
for (auto i : split(str, '"')){
}
3、奇数下标元素加入结果
双引号分割的元素中,奇数下标说明是双引号中的内容,不需要进行空格分割。
std::vector<std::string> args;
if (n++ % 2 == 1)
args.push_back(i);
4、偶数下标元素split空格
偶数下标说明是双引号外的内容,需要进行空格分割。
if (n++ % 2 == 0)
for (auto j : split(i, ' '))
args.push_back(j);
二、完整代码
当前实现,支持双引号。但不支持双引号内嵌入双引号,需要实现也很简单,比如:
定义\
为转移符号,对字符串"\\\""
进行全局替换为'0'
。split操作完之后再将'0'
替换为"\""
。如果'0'
不行则换成其他唯一字符串。
#include <iostream>
#include <sstream>
#include <vector>
#include <string>
static std::vector<std::string> split(const std::string &str, char delim)
{
std::vector<std::string> tokens;
std::istringstream iss(str);
std::string token;
while (std::getline(iss, token, delim))
if (!token.empty())
tokens.push_back(token);
return tokens;
}
static std::vector<std::string> parseArgv(const std::string &str)
{
std::vector<std::string> args;
int n = 0;
for (auto i : split(str, '"'))
{
if (n++ % 2 == 0)
for (auto j : split(i, ' '))
args.push_back(j);
else
args.push_back(i);
}
return args;
}
三、使用示例
1、解析命令行
auto strArgv = parseArgv("ffmpeg -i \"D:\\my video\\test.mp4\" -f null _");
for (auto i : strArgv)
{
printf("%s\n", i.c_str());
}
2、构造argc、argv
auto strArgv = parseArgv("ffmpeg -i \"D:\\my video\\test.mp4\" -f null _");
std::vector<char*> argv;
for (int i = 0; i < strArgv.size(); i++)
argv.push_back((char*)strArgv[i].c_str());
// 调用ffmpeg的main
main(argv.size(), argv.data());
总结
以上就是今天要讲的内容,本文的实现是比较简单的,用的方法算是比较巧妙,只要支持split就可以用本文的方法实现命令行的解析。