我有一个字符串需要分割成标记。
但是 C strtok()
函数要求我的字符串是char*
类型的。
如何简单地实现这个需求?
我已经尝试过:
token = strtok(str.c_str(), " ");
它失败的原因是它将其转换为 const char*
而不是 char*
The reason for its failure is that it converts it into a
const char*
instead of a char*
.我有一个字符串需要分割成标记。
但是 C strtok()
函数要求我的字符串是char*
类型的。
如何简单地实现这个需求?
我已经尝试过:
token = strtok(str.c_str(), " ");
它失败的原因是它将其转换为 const char*
而不是 char*
const char*
instead of a char*
.std::string data("The data I want to tokenize");
// Create a buffer of the correct length:
std::vector<char> buffer(data.size()+1);
// copy the string into the buffer
strcpy(&buffer[0],data.c_str());
// Tokenize
strtok(&buffer[0]," ");
str.c_str()
返回的是常量字符串,但char * strtok (char * str, const char * delimiters )
需要的是易变字符串。所以你需要使用*const_cast< char >来使其成为易变字符串。
我给你一个完整但很小的程序,用C的strtok()函数对字符串进行分词。 #include <iostream>
#include <string>
#include <string.h>
using namespace std;
int main() {
string s="20#6 5, 3";
// strtok requires volatile string as it modifies the supplied string in order to tokenize it
char *str=const_cast< char *>(s.c_str());
char *tok;
tok=strtok(str, "#, " );
int arr[4], i=0;
while(tok!=NULL){
arr[i++]=stoi(tok);
tok=strtok(NULL, "#, " );
}
for(int i=0; i<4; i++) cout<<arr[i]<<endl;
return 0;
}
注意:strtok函数并不适用于所有情况,因为传递给函数的字符串会被分成更小的字符串而被修改。请ref以更好地理解strtok功能。
strtok的工作原理
添加了一些打印语句,以更好地理解每次调用strtok时字符串发生的变化及其如何返回标记。
#include <iostream>
#include <string>
#include <string.h>
using namespace std;
int main() {
string s="20#6 5, 3";
char *str=const_cast< char *>(s.c_str());
char *tok;
cout<<"string: "<<s<<endl;
tok=strtok(str, "#, " );
cout<<"String: "<<s<<"\tToken: "<<tok<<endl;
while(tok!=NULL){
tok=strtok(NULL, "#, " );
cout<<"String: "<<s<<"\t\tToken: "<<tok<<endl;
}
return 0;
}
输出:
string: 20#6 5, 3
String: 206 5, 3 Token: 20
String: 2065, 3 Token: 6
String: 2065 3 Token: 5
String: 2065 3 Token: 3
String: 2065 3 Token:
strtok 迭代字符串,首先找到非分隔符字符(在本例中为 2),将其标记为令牌 start,然后继续扫描分隔符并用空字符替换它(# 在实际字符串中被替换),并返回指向令牌起始字符的 start(即返回以 null 终止的令牌 20)。在后续调用中,它从下一个字符开始扫描,并在找到令牌时返回该令牌,否则返回 null。随后它返回令牌 6、5、3。
c_str()
的结果来修改字符串会导致未定义的行为。 - M.M将类型转换为(char*)对我有用!
token = strtok((char *)str.c_str(), " ");
#include <iostream>
using namespace std;
size_t __wstok(wstring * ws_mystring , wstring * ws_word , const wchar_t c)
{//size_t __wstok
wstring mywstr = * ws_mystring;
size_t found = mywstr.find_first_of(c) ;
if (found != wstring::npos)
{//if (found != wstring::npos)
*ws_word = mywstr.substr(0,found) ;
*ws_mystring = mywstr.substr(found+1 , mywstr.size() );
}//if (found != wstring::npos)
if (found == wstring::npos)
*ws_word = mywstr;
return(found);
}//size_t __wstok
// main
int main()
{
wstring a_wstring = L"every good boy deserves fudge";
wstring a_word; // the string where the result is stored every time.
while (__wstok(&a_wstring, &a_word, L' ' ) != wstring::npos)
{//while
wcout << a_word.c_str() << L"\n\n";
}//while
wcout << a_word.c_str() << L"\n\n"; // last string
return(0);
}
strtok
函数的行为,其他答案已经涵盖了它(基本上使用非const
重载的.data()
)。如果目标只是分词,那么很多指针的技巧可以避免使用。总的来说,我尽量推荐现代 C++ 的最佳实践,而在 2023 年的 C++ 中,我无法真正推荐以这种风格编程。 - undefined