当前位置:  开发笔记 > 编程语言 > 正文

如何从C宏的值创建一个char字符串?

如何解决《如何从C宏的值创建一个char字符串?》经验,为你挑选了2个好方法。

例如,如何避免两次写'func_name'?

#ifndef TEST_FUN
#  define TEST_FUN func_name
#  define TEST_FUN_NAME "func_name"
#endif

我想遵循单点真相规则.

C预处理器的版本:

$ cpp --version
cpp (GCC) 4.1.2 20070626 (Red Hat 4.1.2-14)

Jonathan Lef.. 73

害羞的人*给了你一个答案的细菌,但只有细菌.在C预处理器中将值转换为字符串的基本技术确实是通过'#'运算符,但所提出的解决方案的简单音译会产生编译错误:

#define TEST_FUNC test_func
#define TEST_FUNC_NAME #TEST_FUNC

#include 
int main(void)
{
    puts(TEST_FUNC_NAME);
    return(0);
}

语法错误在'puts()'行上 - 问题是源中的'stray#'.

在C标准的第6.10.3.2节中,"#运营商",它说:

类似函数的宏的替换列表中的每个#preprocessing token都应该跟一个参数作为替换列表中的下一个预处理标记.

麻烦的是你可以将宏参数转换为字符串 - 但是你不能转换非宏参数的随机项.

所以,要达到你想要的效果,你肯定要做一些额外的工作.

#define FUNCTION_NAME(name) #name
#define TEST_FUNC_NAME  FUNCTION_NAME(test_func)

#include 

int main(void)
{
    puts(TEST_FUNC_NAME);
    return(0);
}

我不清楚你打算如何使用这些宏,以及你打算如何完全避免重复.这个稍微复杂的例子可能会提供更多信息.使用等效于STR_VALUE的宏是获得所需结果所必需的习惯用法.

#define STR_VALUE(arg)      #arg
#define FUNCTION_NAME(name) STR_VALUE(name)

#define TEST_FUNC      test_func
#define TEST_FUNC_NAME FUNCTION_NAME(TEST_FUNC)

#include 

static void TEST_FUNC(void)
{
    printf("In function %s\n", TEST_FUNC_NAME);
}

int main(void)
{
    puts(TEST_FUNC_NAME);
    TEST_FUNC();
    return(0);
}

*在第一次写这个答案时,shoosh的名字使用'Shy'作为名字的一部分.



1> Jonathan Lef..:

害羞的人*给了你一个答案的细菌,但只有细菌.在C预处理器中将值转换为字符串的基本技术确实是通过'#'运算符,但所提出的解决方案的简单音译会产生编译错误:

#define TEST_FUNC test_func
#define TEST_FUNC_NAME #TEST_FUNC

#include 
int main(void)
{
    puts(TEST_FUNC_NAME);
    return(0);
}

语法错误在'puts()'行上 - 问题是源中的'stray#'.

在C标准的第6.10.3.2节中,"#运营商",它说:

类似函数的宏的替换列表中的每个#preprocessing token都应该跟一个参数作为替换列表中的下一个预处理标记.

麻烦的是你可以将宏参数转换为字符串 - 但是你不能转换非宏参数的随机项.

所以,要达到你想要的效果,你肯定要做一些额外的工作.

#define FUNCTION_NAME(name) #name
#define TEST_FUNC_NAME  FUNCTION_NAME(test_func)

#include 

int main(void)
{
    puts(TEST_FUNC_NAME);
    return(0);
}

我不清楚你打算如何使用这些宏,以及你打算如何完全避免重复.这个稍微复杂的例子可能会提供更多信息.使用等效于STR_VALUE的宏是获得所需结果所必需的习惯用法.

#define STR_VALUE(arg)      #arg
#define FUNCTION_NAME(name) STR_VALUE(name)

#define TEST_FUNC      test_func
#define TEST_FUNC_NAME FUNCTION_NAME(TEST_FUNC)

#include 

static void TEST_FUNC(void)
{
    printf("In function %s\n", TEST_FUNC_NAME);
}

int main(void)
{
    puts(TEST_FUNC_NAME);
    TEST_FUNC();
    return(0);
}

*在第一次写这个答案时,shoosh的名字使用'Shy'作为名字的一部分.



2> jfs..:

@Jonathan Leffler:谢谢.你的解决方案有效

一个完整的工作示例:

/** compile-time dispatch 

   $ gcc -Wall -DTEST_FUN=another_func macro_sub.c -o macro_sub && ./macro_sub
*/
#include 

#define QUOTE(name) #name
#define STR(macro) QUOTE(macro)

#ifndef TEST_FUN
#  define TEST_FUN some_func
#endif

#define TEST_FUN_NAME STR(TEST_FUN)

void some_func(void)
{
  printf("some_func() called\n");
}

void another_func(void)
{
  printf("do something else\n");
}

int main(void)
{
  TEST_FUN();
  printf("TEST_FUN_NAME=%s\n", TEST_FUN_NAME);
  return 0;
}

例:

$ gcc -Wall -DTEST_FUN=another_func macro_sub.c -o macro_sub && ./macro_sub
do something else
TEST_FUN_NAME=another_func

推荐阅读
手机用户2402852387
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有