You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言指针传字符串函数问题:统计独立子串出现次数

问题分析与修复方案

你的代码核心问题在于**strtok会修改传入的字符串**,但你传入的是字符串字面量(比如"abc of abc of"或char* test指向的内容),这类字符串存储在程序的只读数据段,尝试修改会触发未定义行为,导致程序崩溃或异常。

另外,当前代码只以空格作为单词分隔符,虽然符合你的示例场景,但可以优化为支持更通用的单词边界判断,比如标点,不过先解决核心的只读字符串问题。

修复后的代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int countTargetString(const char* text, const char* target) {
    // 复制原字符串到可写内存,避免修改只读字面量
    char* text_copy = malloc(strlen(text) + 1);
    if (text_copy == NULL) {
        perror("malloc failed");
        return 0;
    }
    strcpy(text_copy, text);

    const char* delimiters = " \t\n.,!?;"; // 扩展分隔符,覆盖常见单词边界
    char* portion = strtok(text_copy, delimiters);
    int result = 0;

    while (portion != NULL) {
        if (strcmp(portion, target) == 0) {
            result++;
        }
        portion = strtok(NULL, delimiters);
    }

    free(text_copy); // 释放动态分配的内存
    return result;
}

int main() {
    printf("%d\n", countTargetString("abc of", "of"));          // 输出1
    printf("%d\n", countTargetString("abcof", "of"));           // 输出0
    printf("%d\n", countTargetString("abc of abc of", "of"));   // 输出2

    // 使用指针指向字符串字面量也能正常运行
    const char* test = "abc of abc of";
    const char* target = "of";
    printf("%d\n", countTargetString(test, target));            // 输出2

    return 0;
}

关键修改点

  • 参数声明为const char*:明确函数不会修改原输入字符串,同时兼容字符串字面量和可写数组。
  • 动态复制字符串:用malloc为原字符串分配可写内存,strtok修改的是这个副本,不会触发只读内存的错误。
  • 扩展分隔符:增加制表符、换行符和常见标点,让单词判断更符合实际场景,比如"of,"这类带标点的情况不会被误统计。
  • 内存释放:使用完动态分配的内存后用free释放,避免内存泄漏。

原代码的其他问题说明

  1. 直接传递字符串字面量给strtok:字符串字面量是只读的,strtok尝试修改它会导致程序崩溃或异常行为。
  2. char d[]=" "; 仅定义空格作为分隔符,无法处理其他可能的单词边界,鲁棒性不足。

内容的提问来源于stack exchange,提问作者Muhito

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 18:31:01