我有一个我想要标记的字符串.但是C strtok()
函数需要我的字符串char*
.我怎么能这么做呢?
我试过了:
token = strtok(str.c_str(), " ");
因为把它变成a const char*
而不是a 而失败了char*
#include#include #include int main(){ std::string myText("some-text-to-tokenize"); std::istringstream iss(myText); std::string token; while (std::getline(iss, token, '-')) { std::cout << token << std::endl; } return 0; }
或者,如上所述,使用boost可以获得更大的灵活性.
如果升压为你的系统上(我认为这是大多数Linux发行版,这些天标准),它有一个标记生成器,你可以使用类.
如果没有,那么快速谷歌会为std :: string 打开一个手动滚动的标记器,你可以复制和粘贴它.它很短.
而且,如果你不喜欢其中任何一个,那么这里是我写的一个split()函数,让我的生活更轻松.它会使用"delim"中的任何字符作为分隔符将字符串分解成碎片.片断被附加到"部分"向量:
void split(const string& str, const string& delim, vector& parts) { size_t start, end = 0; while (end < str.size()) { start = end; while (start < str.size() && (delim.find(str[start]) != string::npos)) { start++; // skip initial whitespace } end = start; while (end < str.size() && (delim.find(str[end]) == string::npos)) { end++; // skip to end of word } if (end-start != 0) { // just ignore zero-length strings. parts.push_back(string(str, start, end-start)); } } }
复制字符串,对其进行标记,然后释放它.
char *dup = strdup(str.c_str()); token = strtok(dup, " "); free(dup);
有一个更优雅的解决方案.
使用std :: string,您可以使用resize()分配适当大的缓冲区,使用&s [0]来获取指向内部缓冲区的指针.
在这一点上,许多优秀的人都会在屏幕上大喊大叫.但这是事实.大约2年前
图书馆工作组决定(在利勒哈默尔召开会议)就像std :: vector一样,std :: string也应该正式地,而不仅仅是在实践中,有一个保证连续的缓冲区.
另一个问题是strtok()增加了字符串的大小.MSDN文档说:
每次调用strtok都会通过在该调用返回的标记之后插入空字符来修改strToken.
但这不正确.实际上,该函数用\ 0 替换第一次出现的分隔符.字符串的大小没有变化.如果我们有这个字符串:
一二三四
我们最终会结束
一个\ 0two\0 - 三\ 0四
所以我的解决方案非常简单:
std::string str("some-text-to-split"); char seps[] = "-"; char *token; token = strtok( &str[0], seps ); while( token != NULL ) { /* Do your thing */ token = strtok( NULL, seps ); }
阅读讨论 http://www.archivum.info/comp.lang.c++/2008-05/02889/does_std::string_have_something_like_CString::GetBuffer