You need to enable JavaScript to run this app. C++中如何处理指针指向的strtok拆分所得单词的内存空间
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.23 13:24:04