首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++宏中的变量字符串连接

C++宏中的变量字符串连接
EN

Stack Overflow用户
提问于 2021-09-15 07:58:32
回答 2查看 145关注 0票数 0

下面是一个返回字符串指针的函数,这个函数是多态性的,这意味着它可以返回任何同学的名字。

代码语言:javascript
复制
const char* get_classmate_name(void);

下面是一个任务,要求您在每个同学的文件夹下的info.txt中放入/获取同学的信息,例如:

代码语言:javascript
复制
/good_class/Anderson/info.txt/
/good_class/Cindy/info.txt/
/good_class/Lily/info.txt/

我尝试用define macro定义这些属性:

代码语言:javascript
复制
#define CLASS_PATH "/good_class"
#define CLASSMATE_PATH CLASS_PATH##"/"get_classmate_name() //wrong
#define CLASSMATE_INFO_PATH CLASSMATE_PATH"/info.txt"

显然,第二个宏是错误的,因为它不允许使用##运算符将符号常量(在本例中为CLASS_PATH )与const char*连接起来。

我希望程序简单,就像这样

代码语言:javascript
复制
static bool folder_is_found(const char* folder_path);

int main(void)
{
    if ((!folder_is_found(CLASS_PATH)) || (!folder_is_found(CLASSMATE_PATH)))
    {
        reutrun -1;
    }

    const char* classmate_height = get_classmate_height(CLASSMATE_INFO_PATH);
    printf("classmate's height is :%s", classmate_height);

    return 0;
}

如何正确定义CLASSMATE_PATH

EN

回答 2

Stack Overflow用户

发布于 2021-09-15 08:22:05

宏不是函数,即使有时它们看起来很相似。

在C代码编译开始之前,会对

  • 宏进行评估。在预处理阶段(即在C代码编译之前),预处理器不知道任何关于宏中的C language.

  • ##连接标记的信息。##所做的事情与相邻的字符串文字的连接完全不同(两者都必须是字符串文字,并且连接发生在编译时,而不是运行时)。

您需要使用函数而不是宏来实现您想要的功能。

票数 1
EN

Stack Overflow用户

发布于 2021-09-15 08:23:31

您不能将CLASSMATE_PATH定义为宏,因为同学的名字(通过get_classmate_name()获得)只在运行时知道,而不是在编译时知道。

一个可以用来一次连接多个字符串的函数是snprintf()

代码语言:javascript
复制
char* get_classmate_path(void) {
  const size_t max_path_size = 200;

  char* res = malloc(max_path_size);
  if (res == NULL) {
    return NULL;
  }

  int bytes = snprintf(res, max_path_size, "%s/%s", CLASS_PATH, get_classmate_name());

  if (bytes < 0 || (size_t) bytes >= max_path_size) {
    free(res);
    return NULL;
  }

  return res;
}

int main(void) {
  printf("Classmate path: %s\n", get_classmate_path());
  // POSSIBLE OUTPUT: Classmate path: /good_class/Anderson
}

因此,将更多的字符串连接在一起是微不足道的:

代码语言:javascript
复制
char* get_classmate_info_path(void) {
  const size_t max_path_size = 200;

  char* res = malloc(max_path_size);
  if (res == NULL) {
    return NULL;
  }

  int bytes = snprintf(res, max_path_size, "%s/%s/info.txt", CLASS_PATH, get_classmate_name());

  if (bytes < 0 || (size_t) bytes >= max_path_size) {
    free(res);
    return NULL;
  }

  return res;
}

注意:前面的示例使用了动态内存分配(通过malloc());您可能想详细了解一下C中的动态内存是如何工作的(例如,您应该在使用完get_classmate_path()的结果之后调用free(),但这超出了答案的范围)。

注2:前面的函数(get_classmate_path()get_classmate_info_path())可能会在出现错误时返回NULL

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69189182

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档