使用 string::find 和 string::substr 拆分字符串的函数返回错误的标记
Function to split strings using string::find and string::substr returns wrong tokens
//splits a string into a vector of multiple tokens
std::vector<string> split_str(std::string& str, const char* delimiter){
std::vector<string> ret;
size_t currPos = 0;
//Add the first element to the vector
if (str.find(delimiter) != string::npos)
ret.push_back(str.substr(currPos, str.find(delimiter)));
while (currPos != str.size() - 1){
if (str.find(delimiter, currPos) != string::npos){
//Current at one past the delimiter
currPos = str.find(delimiter, currPos) + 1;
//Substring everything from one past the delimiter until the next delimiter
ret.push_back(str.substr(currPos, str.find(delimiter, currPos)));
}
//If last whitespace is not right at the end
else if (currPos < str.size()){
//Add the last element to the vector and end the loop
ret.push_back(str.substr(currPos, str.size()));
currPos = str.size() - 1;
}
}
return ret;
}
该程序应该将字符串和分隔符作为输入,并返回字符串(标记(向量作为输出。但是,当我尝试使用简单的输入时,例如:
ab bc cd de (分隔符为 " "(
输出将是 5 个元素:"ab"、"bc cd"、"cd de"、"de"、"de">
问题是要std::string::substr()
的第二个参数是计数而不是位置。您的代码应从以下位置修改:
if (str.find(delimiter) != string::npos)
ret.push_back(str.substr(currPos, str.find(delimiter)));
对此:
auto fpos = str.find(delimiter);
if (fpos != string::npos)
ret.push_back(str.substr(currPos, fpos - currPos));
// ^^^^^^^^^^^^^^
等等。
使用 find_first_of
而不是 find
会更正确。考虑到字符串中可以有相邻的空白,而且字符串可以从空白开始。
这是一个演示性图片,展示了如何编写函数
#include <iostream>
#include <string>
#include <vector>
std::vector<std::string> split_str( const std::string &s, const char *delimiter )
{
std::vector<std::string> v;
size_t n = 0;
for ( std::string::size_type pos = 0;
( pos = s.find_first_not_of( delimiter, pos ) ) != std::string::npos;
pos = s.find_first_of( delimiter, pos ) )
{
++n;
}
v.reserve( n );
for ( std::string::size_type pos = 0;
( pos = s.find_first_not_of( delimiter, pos ) ) != std::string::npos; )
{
auto next_pos = s.find_first_of( delimiter, pos );
if ( next_pos == std::string::npos ) next_pos = s.size();
v.push_back( s.substr( pos, next_pos - pos ) );
pos = next_pos;
}
return v;
}
int main()
{
std::string s( "ab bc cd de " );
std::cout << s << std::endl;
auto v = split_str( s, " " );
for ( auto t : v ) std::cout << t << std::endl;
return 0;
}
程序输出为
ab bc cd de
ab
bc
cd
de
相关文章:
- std中有类似find_last_of的函数,而string中没有
- 使用 std::string () const 函数启动线程或未来
- SegFault 同时使用 std::string::operator+= 和函数作为参数
- std::string 构造函数如何处理固定大小的 char[]?
- 确切地说,如何解释 std::getline(stream, string) 函数在C++中填充的字符串
- 真的没有来自 std::string_view 的 std::string 的显式构造函数吗?
- 构造函数采用std::string_view与std::string并移动
- 为什么我的函数接受"std::string"进行排序不会改变它?
- std::string 可以作为 nlohmann::json 传递给显式构造函数
- 错误:调用"es_queue::set_rpc_vector(std::vector >&, std::__cxx11::string)"没有匹配函数
- 我正在将一个 std::string 传递给一个 boost 函数,该函数对该类型进行常量引用,但该值发生了变化
- 无效打印(矢量<string>)函数未打印
- 为什么我不必从 std::string 的函数中释放字符串c_str?
- 将(临时的?)std::string传递给使用它来构造一个接受副本的对象的函数的最佳方法是什么?
- C++ 模板函数无法将"std:string"转换为"double"作为回报
- 在线程中使用 std::string 函数是否安全?(C++)
- C++ 对 MBCS 使用 std::string 函数,对 UTF-16 使用 std::wstring 函数
- C++:STRING函数返回十六进制值而不是字符串
- 使用插入<string>函数时从字符到常量字符的转换无效
- C++:向量<通过<string>函数设置>初始化