C++ 如何改进这段关于strtok\u r的代码
我想通过分隔符从std::string中提取一些令牌,并编写如下函数,但仍然存在错误:C++ 如何改进这段关于strtok\u r的代码,c++,string,strtok,C++,String,Strtok,我想通过分隔符从std::string中提取一些令牌,并编写如下函数,但仍然存在错误: enum TO_TYPE { TO_INT=0, TO_FLOAT, TO_STRING}; template<typename T> vector<T> string_to_token(string &str, const char* delim, TO_TYPE to_type) { char *p=new char[str
enum TO_TYPE { TO_INT=0, TO_FLOAT, TO_STRING};
template<typename T>
vector<T> string_to_token(string &str, const char* delim, TO_TYPE to_type)
{
char *p=new char[str.size()];
memcpy(p,str.c_str(),str.size());
switch(to_type)
{
case TO_INT:
{
vector<int> res;
char *token;
char *state;
for (token = strtok_r(p, delim, &state);
token != NULL;
token = strtok_r(NULL, delim, &state))
{
res.push_back(atoi(token));
}
delete[] p;
return res;
}
break;
case TO_FLOAT:
{
vector<float> res;
char *token;
char *state;
for (token = strtok_r(p, delim, &state);
token != NULL;
token = strtok_r(NULL, delim, &state))
{
res.push_back(atof(token));
}
delete[] p;
return res;
}
break;
case TO_STRING:
{
vector<string> res;
char *token;
char *state;
for (token = strtok_r(p, delim, &state);
token != NULL;
token = strtok_r(NULL, delim, &state))
{
res.push_back(string(token));
}
delete[] p;
return res;
}
break;
}
}
enum TO_TYPE{TO_INT=0,TO_FLOAT,TO_STRING};
模板
向量字符串\u到\u标记(字符串&str,常量字符*delim,到\u类型到\u类型)
{
char*p=新字符[str.size()];
memcpy(p,str.c_str(),str.size());
开关(至_型)
{
案件编号:
{
向量res;
字符*令牌;
字符*状态;
for(token=strtok_r(p、delim和state);
令牌!=NULL;
token=strtok_r(NULL、delim和state))
{
res.push_back(atoi(token));
}
删除[]p;
返回res;
}
打破
浮点数的情况:
{
向量res;
字符*令牌;
字符*状态;
for(token=strtok_r(p、delim和state);
令牌!=NULL;
token=strtok_r(NULL、delim和state))
{
res.push_back(atof(token));
}
删除[]p;
返回res;
}
打破
大小写到字符串:
{
向量res;
字符*令牌;
字符*状态;
for(token=strtok_r(p、delim和state);
令牌!=NULL;
token=strtok_r(NULL、delim和state))
{
res.push_back(字符串(令牌));
}
删除[]p;
返回res;
}
打破
}
}
用法:
string str="lab,yuv,hsv";
vector<string> colorspace=string_to_token<string>(str,",");
string str=“实验室、yuv、hsv”;
向量颜色空间=字符串\u到\u标记(str,“,”);
它在返回res
行中有错误
我曾尝试使用void(*change\u func)(char*temp\u str)
作为回调函数,但我不知道如何实现它。
如果你方便的话,能给我一些建议吗?非常感谢。出现错误的原因是,您的模板将在编译时指定为(示例为
int
):
模板
向量字符串\u到\u标记(字符串&str,常量字符*delim,到\u类型到\u类型)
{
// ...
开关(至_型)
{
案件编号:
{
向量res;
// ...
return res;//这没问题
}
打破
浮点数的情况:
{
向量res;
// ...
return res;//这将尝试为向量返回向量
}
打破
大小写到字符串:
{
向量res;
// ...
return res;//这将尝试为向量返回向量
}
打破
}
}
实际上,您正试图用此函数解决两个问题:
- 标记化(参见解决方案)
- 字符串转换
- 首先是一个非模板函数,它将字符串标记为std::vector
- 第二,转换(可以通过类型轻松模板化):
std::vector strings=tokenize(str,”,”;//见上面的链接
std::vector int{strings.size()};
std::transform(strings.begin()、strings.end()、ints.begin(),
[](const std::string&s){return std::stoi(s);});
在枚举中将其模板化为_TYPE
并在运行时保存一个分支谢谢。但我不太清楚你说了什么。我已经使用了模板参数,但它不起作用。我已经实现了三个独立的功能。非常清晰的解决方案。非常感谢。我应该更多地了解C++。
template<>
vector<int> string_to_token(string &str, const char* delim, TO_TYPE to_type)
{
// ...
switch(to_type)
{
case TO_INT:
{
vector<int> res;
// ...
return res; // this is OK
}
break;
case TO_FLOAT:
{
vector<float> res;
// ...
return res; // this will attempt to return vector<float> for a vector<int>
}
break;
case TO_STRING:
{
vector<string> res;
// ...
return res; // this will attempt to return vector<string> for a vector<int>
}
break;
}
}
std::vector<std::string> strings = tokenize(str, ","); // see link above
std::vector<int> ints{strings.size()};
std::transform(strings.begin(), strings.end(), ints.begin(),
[](const std::string& s) { return std::stoi(s); });