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

含转义字符的文件名无法通过sprintf拼接路径的修复问题

修复含反斜杠文件名的路径拼接问题

我写了一个C语言函数,用来接收目录路径和文件名,通过检查目录末尾是否带/来拼接完整路径。但发现如果文件名里包含\字符,sprintf就没法正确拼接字符串;文件名不含\时一切正常,该怎么修复?

我的代码如下:

char * find_endwith_slash(char *dir_path, char *file_name)
{
    char full_path[1024];
    if (dir_path[strlen(dir_path) - 1] != '/')
    {
        sprintf(full_path, "%s/%s", dir_path, file_name);
    }
    else
    {
        sprintf(full_path, "%s%s", dir_path, file_name);
    }

    char * full_name = malloc(strlen(full_path) * sizeof(char));
    full_name = strdup(full_path);

    return full_name;

}

问题根源

  1. sprintf的转义特性:sprintf会把输入字符串里的\当成转义符处理(比如\n会被解析为换行),而非普通字符,导致文件名中的反斜杠被错误解析,最终拼接结果不符合预期。
  2. 栈缓冲区溢出风险:full_path是固定大小的栈数组(1024字节),如果拼接后的路径长度超过这个值,会触发缓冲区溢出,引发未定义行为。
  3. 内存泄漏:先malloc分配内存,随后用strdup的返回值覆盖指针,导致malloc的内存永远无法释放。

修复方案

方案1:用strcpy+strcat替代sprintf(推荐)

字符串拼接函数会直接复制所有普通字符,不会处理转义,完美适配带反斜杠的文件名:

char * find_endwith_slash(char *dir_path, char *file_name)
{
    size_t dir_len = strlen(dir_path);
    size_t file_len = strlen(file_name);
    // 计算总内存:目录长度 + 可能的1个/ + 文件名长度 + 1(字符串终止符)
    size_t total_len = dir_len + (dir_path[dir_len - 1] != '/' ? 1 : 0) + file_len + 1;

    char *full_name = malloc(total_len);
    if (!full_name) return NULL; // 必须检查内存分配是否成功

    strcpy(full_name, dir_path);
    if (dir_path[dir_len - 1] != '/') {
        strcat(full_name, "/");
    }
    strcat(full_name, file_name);

    return full_name;
}

方案2:改用snprintf替代sprintf(如果坚持用格式化函数)

snprintf可以避免缓冲区溢出,同时只要文件名里的\是原始字符(不是转义后的),直接使用即可:

char * find_endwith_slash(char *dir_path, char *file_name)
{
    size_t dir_len = strlen(dir_path);
    size_t file_len = strlen(file_name);
    size_t total_len = dir_len + (dir_path[dir_len - 1] != '/' ? 1 : 0) + file_len + 1;

    char *full_name = malloc(total_len);
    if (!full_name) return NULL;

    if (dir_path[dir_len - 1] != '/') {
        snprintf(full_name, total_len, "%s/%s", dir_path, file_name);
    } else {
        snprintf(full_name, total_len, "%s%s", dir_path, file_name);
    }

    return full_name;
}

关键修复点

  • 移除了内存泄漏:直接根据实际需求分配内存,不再重复分配后丢弃指针。
  • 消除栈溢出风险:用动态分配的堆内存替代固定大小的栈数组。
  • 增加内存分配失败检查:避免返回空指针导致后续操作崩溃。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 18:35:51