C预处理器宏用于返回重复一定次数的字符串

son*_*tam 13 c macros c-preprocessor

有人知道任何C99预处理器魔法允许创建一个由另一个重复N次的字符串组成的字符串吗?

例如

STRREP( "%s ", 3 )
Run Code Online (Sandbox Code Playgroud)

"%s %s %s "
Run Code Online (Sandbox Code Playgroud)

经过预处理.

我能想到的唯一一件事就是这样

#define STRREP( str, N ) STRREP_##N( str )    
#define STRREP_0(str) ""
#define STRREP_1(str) str
#define STRREP_2(str) str str
#define STRREP_3(str) str str str
...
Run Code Online (Sandbox Code Playgroud)

哪个效果很好,但是很难看,因为我必须手动为每个重复长度定义一个宏.我想与variadic宏一起使用它,宏返回这里显示的宏参数的数量.

Ale*_*nze 22

因为它是一个宏而且N是一个数值常量,这个怎么样?

#include <stdio.h>

#define REP0(X)
#define REP1(X) X
#define REP2(X) REP1(X) X
#define REP3(X) REP2(X) X
#define REP4(X) REP3(X) X
#define REP5(X) REP4(X) X
#define REP6(X) REP5(X) X
#define REP7(X) REP6(X) X
#define REP8(X) REP7(X) X
#define REP9(X) REP8(X) X
#define REP10(X) REP9(X) X

#define REP(HUNDREDS,TENS,ONES,X) \
  REP##HUNDREDS(REP10(REP10(X))) \
  REP##TENS(REP10(X)) \
  REP##ONES(X)

int main(void)
{
  printf(REP(9,0,7, "*")); // "*" repeated 907 times
  printf(REP(0,9,2, "#")); // "#" repeated 92 times
  printf(REP(0,0,1, "@")); // "@" repeated 1 times
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

  • \*呕吐遍布屏幕\*但它很容易使用虽然+1 (10认同)

BLU*_*IXY 6

我的建议是使用boost。

例如

#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("%s ", 3));//STRREP("%s ", 3) -> "%s %s %s "
    return 0;
}
Run Code Online (Sandbox Code Playgroud)


Mar*_*lli 5

我最近发现了一种递归方案,其中 CPP c 预处理器文件包含机制超过了自动处理的 __INCLUDE_LEVEL__ 预处理器文字 - 所以也许这个算法只适用于 gcc ?!?

  • 该算法在概念上是无限的,可以通过附加文件间接进行扩展。
  • 这里提供的代码处理 0-39202 之间的 ITERATION_COUNT
  • 通过 ITERATION_SEPARATOR 的注释/取消注释,您可以生成 N 个元素,或 1 个具有 N 个串联的元素,适合字符串重复。
  • ITERATION_ELEMENT 宏用作“重复元素”

您可以定期编译代码,无需任何额外的定义。代码内的宏调用是幂等的。

示例性输出:

> gcc iterate.c -o iterate -Wall -s -O3 && ./iterate.exe

0-1591 计数器

1592 元素


迭代.c:

#include <stdio.h>
#include <inttypes.h>

int main(void) {

const char * preproc_array[] = {
#define ITERATION_COUNT         1592                //0-(199*197-1)39202 (maximum counter)
#define ITERATION_SEPARATOR ,                       //this macro, if active, determines wheather there exits N separate elements otherwise, if outcommented, just 1 element with N concatenations
#define ITERATION_ELEMENT   0-__COUNTER__ Counter\n //the expanded macro as an arbitrary element
#include "iterate.h"
};

return !printf("%s%"PRIu32" Elements",preproc_array[
#ifndef NO_ITERATION_SEPARATOR
__COUNTER__-1
#else
0
#endif
], sizeof(preproc_array)/sizeof(const char *));

}
Run Code Online (Sandbox Code Playgroud)

迭代.h:

#define     ITERATION_START 1   //start index of first inclusion
#define     ITERATION_LIMIT     199 //conforming to CPP preprocessor manual pg. 54 chapter 11.5, a limit of 200 is set arbitrary
#define     ITERATION(...)      _ITERATION(__VA_ARGS__)
#define     _ITERATION(...)     #__VA_ARGS__ ITERATION_SEPARATOR

#ifndef ITERATION_SEPARATOR
#define ITERATION_SEPARATOR
#define NO_ITERATION_SEPARATOR
#endif   

//here begins the recursive algorithm via preprocessor file inclusion, enable the warnings if you want to see how it loops through

#if __INCLUDE_LEVEL__   <=  ITERATION_COUNT/ITERATION_LIMIT
//~ #warning DIV
#define ITERATION_END   ITERATION_COUNT/ITERATION_LIMIT+3 // + offset
#include "loop.h"
#define ITERATION_END   ITERATION_LIMIT
#include "loop.h"
#include "iterate.h"
#endif

#if __INCLUDE_LEVEL__   ==  ITERATION_START
//~ #warning MOD
#define ITERATION_END   ITERATION_COUNT%ITERATION_LIMIT+ITERATION_START
#include "loop.h"
#if ITERATION_COUNT     %   ITERATION_LIMIT
#define ITERATION_END   3   // + offset
#include "loop.h"
#endif
#endif

//end of alogrithm
Run Code Online (Sandbox Code Playgroud)

循环.h:

#if __INCLUDE_LEVEL__   <   ITERATION_END
#include "loop.h"
ITERATION(ITERATION_ELEMENT)
#undef ITERATION_END
#endif
Run Code Online (Sandbox Code Playgroud)