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

如何用#define获取无扩展名文件名并存储到PROGMEM中

解决方案

方案1:用构建系统(比如Makefile)生成编译时常量

这是最靠谱、完全没运行时开销的法子——直接通过构建脚本提前处理好文件名,把它定义成编译宏:

操作步骤:

  • 在Makefile里加这段代码(假设你的源文件变量是SOURCE_FILE):
    # 提取不带路径和扩展名的文件名
    MODULE_NAME := $(basename $(notdir $(SOURCE_FILE)))
    # 把它变成编译时可用的宏
    CFLAGS += -DMODULE_NAME="\"$(MODULE_NAME)\""
    
  • 然后在C代码里直接用这个宏定义PROGMEM常量:
    #include <avr/pgmspace.h>
    
    const char PROGMEM module_name[] = MODULE_NAME;
    

这种方法全程在编译前就把文件名处理完了,最终生成的常量直接存在PROGMEM里,程序跑起来根本不用额外做任何操作,内存和性能开销为零。

方案2:靠GCC编译器扩展实现编译时字符串截取

如果没法改构建系统,那就利用GCC的编译时优化特性,直接在代码里写宏——编译器会自动把它优化成常量:

#include <avr/pgmspace.h>
#include <string.h>

// 先拿到不带路径的文件名
#define __FILENAME_NO_PATH__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
// 编译时直接截掉扩展名
#define __FILENAME_NO_EXT__ \
    (__extension__ ({ \
        const char *base = __FILENAME_NO_PATH__; \
        const char *dot = strrchr(base, '.'); \
        // 算好目标字符串长度,生成编译时常量数组
        const size_t len = dot ? (size_t)(dot - base) : strlen(base); \
        char buf[len + 1]; \
        strncpy(buf, base, len); \
        buf[len] = '\0'; \
        buf; \
    }))

// 存到PROGMEM里
const char PROGMEM module_name[] = __FILENAME_NO_EXT__;

GCC能识别__FILE__是字符串字面量,会把strrchr和strlen的计算提前到编译时完成,最终直接生成不含路径和扩展名的字符串常量存入PROGMEM,运行时啥额外操作都不用做。

注意:这个方案依赖GCC的扩展特性,只适用于AVR GCC、ARM GCC这类支持该特性的编译器。

方案3:纯预处理器递归宏(有长度限制)

如果必须用纯预处理器实现(不依赖编译器的运行时优化),可以试试递归宏处理字符串,但要注意——文件名不能太长,得在预处理器的递归上限以内(默认一般是200左右):

#include <avr/pgmspace.h>

// 递归宏:逐个字符扫,碰到'.'或者'\0'就停
#define _STRIP_EXT_CHARS(s, i) \
    (s[i] == '.' || s[i] == '\0' ? '\0' : (s[i], _STRIP_EXT_CHARS(s, i+1)))

// 先拿不带路径的文件名
#define __FILENAME_NO_PATH__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)

// 生成无扩展名的字符串
#define __FILENAME_NO_EXT__ (const char[]){ _STRIP_EXT_CHARS(__FILENAME_NO_PATH__, 0) }

const char PROGMEM module_name[] = __FILENAME_NO_EXT__;

这个方案完全靠预处理器展开生成字符串,但文件名太长的话会触发编译错误,适合短文件名的场景。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 10:27:03