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

C语言按规则拼接字符串时strlen报错、长度计算为负数问题求解

问题1:main函数中大字符串的定义方式

两种安全的定义方案可选,都不会触发strlen报错也不会产生多余空格:

  • 方案1:初始分配1字节存字符串结束符,初始就是空字符串,strlen直接返回0
int main() {
    char* res = malloc(1);
    res[0] = '\0';
    // 后续正常调用add函数拼接字符串
    // 所有操作结束后记得释放内存
    free(res);
    return 0;
}
  • 方案2:初始设为NULL,只要在add函数里调用strlen前先做非空判断即可
// add函数内判断逻辑示例
size_t origin_len = (*addTo == NULL) ? 0 : strlen(*addTo);
问题2:newLength的正确计算方式

你计算得到负数的核心原因是用了有符号的int类型存长度,当拼接的字符串长度超过int的最大值时,数值溢出就会变成负数,需要换用strlen原生返回的无符号类型size_t存长度。
另外你原本的长度计算逻辑也有冗余,正确计算规则如下:

  • 原有已拼接字符串的长度:strlen(*addTo)(空串则为0)
  • 新增单词的长度:strlen(temp)
  • 额外需要加2字节:1字节存单词后面的#,1字节存整个字符串末尾的结束符\0
  • sizeof(char)固定为1,不需要额外乘
size_t newLength = strlen(*addTo) + strlen(temp) + 2;
现有代码其他问题修正

你当前的代码存在死循环问题:strtok第一次调用传原始字符串,后续取分词必须传NULL才能迭代,你写的while(str != NULL)判断中str永远不会被修改,会直接卡死。修正后的完整add函数参考:

void add(char** addTo, char* str, int on)
{
    if (str == NULL || addTo == NULL) return;
    // 处理初始addTo为NULL的情况
    if (*addTo == NULL) {
        *addTo = malloc(1);
        (*addTo)[0] = '\0';
    }
    char* temp = strtok(str, " \n");
    int hasWord = 0;
    while (temp != NULL)
    {
        size_t originLen = strlen(*addTo);
        size_t tempLen = strlen(temp);
        size_t newLength = originLen + tempLen + 2;
        *addTo = realloc(*addTo, newLength);
        // 不是第一个单词先加分隔符#
        if (hasWord) {
            strcat(*addTo, "#");
        }
        strcat(*addTo, temp);
        hasWord = 1;
        // 取下一个分词,必须传NULL
        temp = strtok(NULL, " \n");
    }
    // 不是最后一个小字符串加@分隔符
    if (on) {
        size_t curLen = strlen(*addTo);
        *addTo = realloc(*addTo, curLen + 2);
        strcat(*addTo, "@");
    }
}

内容的提问来源于stack exchange,提问作者יונתן אליהו

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 20:24:03