C 如何使用预处理器宏填充字符串
是否可以仅使用预处理器宏在字符串中填充空格(或任何字符)?如果是,怎么做 例如:C 如何使用预处理器宏填充字符串,c,string,c-preprocessor,C,String,C Preprocessor,是否可以仅使用预处理器宏在字符串中填充空格(或任何字符)?如果是,怎么做 例如: #define SOME_STR "v1.1" #define STR_PAD(str, len) // <-- padding defined string #define SOME_STR_PADDED STR_PAD(SOME_STR, 10) // evaluates to "v1.1 " #定义一些_STR“v1.1”
#define SOME_STR "v1.1"
#define STR_PAD(str, len) // <-- padding defined string
#define SOME_STR_PADDED STR_PAD(SOME_STR, 10) // evaluates to "v1.1 "
#定义一些_STR“v1.1”
#定义STR_PAD(STR,len)/首先,预处理器可以将令牌转换为字符串,但它根本无法修改现有字符串。它所能做的是将字符串文本彼此相邻(“foo”“bar”
),这些文本在编译时被翻译(虽然不是由预处理器正式翻译),相当于连接的字符串(“foobar”
)
因此,您可以这样做:
#define VERSION "v1.1"
#define APPEND_10_SPACES(s) s " "
printf("%s", APPEND_10_SPACES(VERSION));
更困难的是,您还可以安排附加由宏参数指定的许多空格。您的web搜索应该会显示几个与使预处理器模拟迭代有关的结果
然而,预处理器绝对不能做的是确定或使用字符串文字的长度,以便允许您执行与将文字填充到特定长度等效的操作。如果您需要,那么您可能会依赖以下解决方法:
char padded[] = APPEND_10_SPACES(VERSION);
padded[10] = '\0';
您不能通过这种方式获得所需的字符串作为文本,但您确实得到了它,代价是分配的字节比您需要的多10个字节,如果原始字符串实际长度超过10个字符,则将其截断。这是一个非常有趣的问题!在str
和len
都未知的一般情况下,以及在str
单独未知的情况下,这似乎是不可能的。如果已知str
的长度,并且len
受某个合理的固定值限制,则可以生成编译为单个字符串常量的复合三元表达式
下面是一个例子:
// compile time padding: str must be a string constant and len <= 4 + strlen(str)
#define STR_PAD(str, len) (((len) + 1 <= sizeof str) ? str : \
((len) == sizeof str) ? str " " : \
((len) == sizeof str + 1) ? str " " : \
((len) == sizeof str + 2) ? str " " : \
str " ")
//编译时填充:str必须是一个字符串常量,len-Than可能会被改写,这样才能问真正的问题?引用您的话:…我的问题是是否可以填充…
,我的回答是-是的,这是可能的。我问是否可能(a),如果可能,如何做(b)。英语不是我的母语,但我认为它正在逐渐普及。我将改写这个问题,让每个人都能理解。谢谢。非常有趣的问题!在str
和len
都未知的一般情况下,以及在str
单独未知的情况下,这似乎是不可能的。如果已知str
的长度,并且len
由某个合理的固定值限定,则可以生成一个编译为单个字符串常量的复合三元表达式。虽然已经这样回答了,但我想做一个区分,以澄清一些问题。预处理器无法确定字符串常量的长度,因此无法执行要求的操作。但在编译过程中还有很多事情要做;询问预处理器在编译时是否可以pad和您是否可以pad是两个不同的问题(答案不同)。我想,您的意思是“len is<4+sizeof str”comment@Ctx:接得好。由于sizeof(str)==strlen(str)+1
这是个好主意,因此也出现了一个off-by-one错误!我没有想到三元表达式。谢谢你的澄清。当然你是对的,在编译时,除了运行预处理器,还有更多的事情要做。事实上,我想在@chqrlie的答案后面加上不同数量的空格。正如您所提到的,您可能会编写一个包装器来模拟循环。