C++中如何处理指针指向的strtok拆分所得单词的内存空间
现有代码的逻辑问题修正
你当前的写法存在会直接导致功能失效的逻辑偏差:
strtok是带有静态内部状态的C标准库函数:仅首次调用需要传入待拆分的原始字符串地址,后续拆分同一段内容时,第一个参数必须传nullptr,函数才会沿着上次拆分完成的位置继续向后查找下一个目标单词- 现在把
strtok的调用嵌套在遍历字符串长度的for循环内部,会导致每一轮循环都从头开始拆分原始字符串,既无法按顺序拿到所有拆分结果,还会出现重复拆分、逻辑死循环的问题 - 原来的while循环内,第二次及后续调用
strtok时依然传入了原始字符串地址sir,这种写法会让函数每次都从头开始拆分,永远拿不到第一个单词之后的其他内容,同样会陷入死循环 - 包裹拆分逻辑的
for(i = 0; i < strlen(sir); ++i)循环、以及无实际用途的变量i、z完全冗余,可以直接移除
逐字符遍历拆分单词的实现方法
strtok返回的指针p本身就指向拆分完成的单词的首字符,且拆分完成的单词是被函数临时将分隔符替换为\0的、以空字符结尾的标准C风格字符串。要遍历从首字符到尾字符的所有内容,只需要从p的地址开始,逐次向后偏移指针、访问对应位置的字符,直到碰到字符串结束符\0即可。
修正后的可运行示例代码:
#include <iostream> #include <cstring> using namespace std; int main() { char sir[256]; cin.getline(sir, 256); // 首次拆分传入原始字符串地址 char* p = strtok(sir, " ,."); while (p != nullptr) { cout << "当前拆分单词:" << p << endl; cout << "逐字符遍历结果:"; // 从单词首地址开始逐位遍历 for (char* cur = p; *cur != '\0'; cur++) { // 此处*cur就是当前访问到的字符,比如遍历"StackOverflow"时,会依次拿到首字符'S'到尾字符'w'的所有内容 cout << *cur << " "; } cout << endl; // 后续拆分传nullptr,延续上次的查找位置 p = strtok(nullptr, " ,."); } return 0; }
关键说明
- 不需要额外存储每个单词的长度:
strtok在拆分时会自动把单词后方紧邻的分隔符改写为字符串结束符\0,指针偏移碰到\0时就说明已经遍历完当前单词的所有有效字符 - 比如拆分得到
StackOverflow时,p指向'S'的存储位置,依次偏移指针就可以顺序访问t、a、c……直到最后一个字符w,再偏移1位就会碰到结束符,自动终止遍历循环
内容的提问来源于stack exchange,提问作者Marshall
相关产品推荐
相关产品推荐

