【问题标题】:Is there a C macro to generate repeat string? [duplicate]是否有 C 宏来生成重复字符串? [复制]
【发布时间】:2012-07-16 23:41:51
【问题描述】:

假设我要生成------,只有-,有没有C宏可以生成重复字符串?

【问题讨论】:

标签: c++ c macros


【解决方案1】:

是和不是。这并不简单,通常也不是一个好主意,但您可以为有限的、恒定的大小和恒定的字符执行此操作。使用 C 预处理器有很多方法可以做到这一点。这是一个:

#define DUP(n,c) DUP ## n ( c )

#define DUP7(c) c c c c c c c
#define DUP6(c) c c c c c c
#define DUP5(c) c c c c c
#define DUP4(c) c c c c
#define DUP3(c) c c c
#define DUP2(c) c c
#define DUP1(c) c

#include <stdio.h>

int main(int argc, char** argv)
{
  printf("%s\n", DUP(5,"-"));
  printf("%s\n", DUP(7,"-"));
  return 0;
}

它并不漂亮,只有当您真的希望将字符串存储为静态(常量)数据时才有用。 nDUP 的'c' 参数都必须是常量(它们不能是变量)。 Boost.Preprocessor 模块有很多关于如何以及何时(ab)像这样使用 C/C++ 预处理器的有用信息。虽然 Boost 是一个 C++ 库,但预处理器信息在很大程度上适用于纯 C。

一般来说,在普通的 C 代码中这样做会更好:

/* In C99 (or C++) you could declare this: 
     static inline char* dupchar(int c, int n)
   in the hopes that the compiler will inline. C89 does not support inline
   functions, although many compilers offered (inconsistent) extensions for
   inlining. */
char* dupchar(int c, int n)
{
  int i;
  char* s;

  s = malloc(n + 1); /* need +1 for null character to terminate string */
  if (s != NULL) {
    for(i=0; i < n; i++) s[i] = c;
  }
  return s;
}

或者,按照@Jack 的建议使用memset

【讨论】:

  • +1,我认为DUP 宏很聪明,尽管我同意这不是一个好主意。
  • +1 用于宏解决方案。但在dupchar 函数中:必须检查s 是否为非NULL 值;我认为您可以在循环语句的第一个参数中添加关于变量声明的注释是 C99 特性;将c 视为char 不是一个好主意。必须使用int 代替。
  • @Jack:你对 NULL 检查是对的,我已经修复了该函数以符合 C89。不过,为什么要用int 值填充char* 数组呢?
  • @TheMask:无法保证编译器会内联调用malloc 并且具有可变范围的for 循环的函数。
【解决方案2】:

不在 C 标准中。您需要编写自己的实现。

编辑:

类似这样的:

#include <stdio.h>
#include <string.h>

#define REPEAT(buf, size, ch) memset(&buf, ch, size)

int main(void)
{

  char str[10] = { 0 };
  REPEAT(str, 9, '-');
  printf("%s\n", str); //---------

  return 0;
}

【讨论】:

  • memset 似乎是最干净的解决方案。
【解决方案3】:

使用提升,例如

#include <stdio.h>
#include <boost/preprocessor/repetition/repeat.hpp>

#define Fold(z, n, text)  text

#define STRREP(str, n) BOOST_PP_REPEAT(n, Fold, str)

int main(){
    printf("%s\n", STRREP("-", 6));
    return 0;
}

【讨论】:

  • 包括提升吗?就个人而言,我更喜欢做一个简单的循环。
  • @TheMask:同意。为什么要为此增加编译时间(很多)? Boost 是多余的。
  • 可能有点矫枉过正,但另一方面,为什么人们不应该使用专为此类问题设计的工具? BOOST 是一个很棒的库——像这样的好例子会让更多人对使用它感兴趣。
  • @TheMask - 我认为有一个文字,因为我最终想要。
  • @sfstewman - 编译时没有太多时间,但会略有增加。但是,获得的好处更大。此外,无需制作现有的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-20
  • 1970-01-01
  • 2018-10-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多