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

C语言自定义file_name函数提取Windows路径文件名无输出问题排查

代码无法正常运行的核心原因

你的代码存在多个严重的未定义行为,直接导致运行异常:

  • 数组下标非法越界:你初始化i = -1,直接访问addr[i]等价于访问字符串首地址之前的未知内存,完全没有读取到路径的末尾字符。C语言字符串的下标从0开始,要从末尾遍历首先需要调用strlen获取字符串总长度,从下标长度-1的位置开始倒序遍历。
  • 循环无边界保护:如果传入的路径没有反斜杠,循环会一直向低地址越界读取内存,直到碰巧读到值为'\\'的字节,或者触发内存访问错误导致程序崩溃,这就是你遇到卡顿后退出的核心原因。
  • 字符串缺少结束标记:你向name数组写入完文件名后没有追加'\0'结束符,C语言的字符串依赖'\0'判断结束,后续printf读取时会越界访问name数组之外的内存,输出乱码或者触发异常。
  • 反转逻辑错误:反转数组的循环条件写为count < len,会导致每个字符被交换两次,最终回到倒序状态,正确的反转应该只遍历前半段,条件为count < len / 2。
static修饰局部变量的原理

C语言的变量根据存储位置分为三类:

  1. 栈区变量:默认的局部变量都存在栈区,函数调用结束后栈帧会被回收,对应的变量内存会被后续操作覆盖,直接返回栈区变量的地址是非法操作,访问时会出现未定义行为。
  2. 静态存储区变量:被static修饰的局部变量会被放到静态存储区,整个程序运行周期内这块内存都不会被释放,地址持续有效,所以返回它的指针是合法的。但注意静态变量是全局共享的,多次调用函数会覆盖之前存储的内容,不支持多线程安全使用。
  3. 堆区变量:通过malloc动态申请的内存存在堆区,需要手动调用free释放,生命周期由开发者控制。
C标准库的现成路径处理函数

C标准本身没有规定专门的文件名提取函数,但不同平台有成熟的实现:

  • Windows平台MSVC/MinGW都支持_splitpath函数,可以直接拆分路径的盘符、目录、文件名、后缀四个部分。
  • 符合POSIX标准的环境(包括Windows下的GCC)可以通过包含<libgen.h>头文件,调用basename()函数,直接传入路径字符串即可返回文件名部分的指针。
修正后的参考实现
#include <string.h>

char* file_name(char* addr) {
    static char name[100];
    int len = strlen(addr);
    int i = len - 1;
    int name_len = 0;
    // 从末尾找第一个反斜杠
    while (i >= 0 && addr[i] != '\\') {
        i--;
    }
    // 拷贝文件名,i+1就是文件名的起始下标
    name_len = len - (i + 1);
    if (name_len >= 100) name_len = 99; // 防止数组越界
    strncpy(name, addr + i + 1, name_len);
    name[name_len] = '\0'; // 追加字符串结束符
    return name;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 16:36:03