我有一个C-program(一个Apache模块,即程序经常运行),它会通过套接字write()
以0结尾的字符串,所以我需要知道它的长度。 / p>
字符串#defined为:
#define POLICY "<?xml version=\"1.0\"?>\n" \
"<!DOCTYPE cross-domain-policy SYSTEM\n" \
"\"http://www.adobe.com/xml/dtds/cross-domain-policy.dtd\">\n" \
"<cross-domain-policy>\n" \
"<allow-access-from domain=\"*\" to-ports=\"8080\"/>\n" \
"</cross-domain-policy>\0"
请问一种方法,比在运行时使用strlen(POLICY)+1
更好(从而一次又一次地计算长度)?
预处理程序指令,它允许在编译时设置POLICY_LENGTH
?
答案 0 :(得分:32)
使用sizeof()
。例如sizeof("blah")
将在编译时评估为5
(5,而不是4,因为字符串文字总是包含隐式的空终止字符)。
答案 1 :(得分:6)
使用1+strlen(POLICY)
并启用编译器优化。如果在编译时已知S的值,GCC将在编译时用长度S替换strlen(S)。
答案 2 :(得分:2)
sizeof
在编译时工作
#define POLICY "<?xml version=\"1.0\"?>\n" \
"<!DOCTYPE cross-domain-policy SYSTEM\n" \
"\"http://www.adobe.com/xml/dtds/cross-domain-policy.dtd\">\n" \
"<cross-domain-policy>\n" \
"<allow-access-from domain=\"*\" to-ports=\"8080\"/>\n" \
"</cross-domain-policy>\0"
char pol[sizeof POLICY];
strcpy(pol, POLICY); /* safe, with an extra char to boot */
如果你需要一个大小的预处理器符号,只需计算字符并自己编写符号: - )
#define POLICY_LENGTH 78 /* just made that number up! */
答案 3 :(得分:1)
在嵌入式平台上使用过时的编译器(VisualDSP)时我遇到了类似的问题,该平台尚不支持C ++ 11(因此我不能使用constexpr)。
我不需要在预编译器中评估字符串长度,但我确实需要将其优化为单个赋值。
以防万一将来有人需要这个,这是我非常讨厌的解决方案,只要他们进行适当的优化,它们就可以应用于糟糕的编译器:
#define STRLENS(a,i) !a[i] ? i : // repetitive stuff
#define STRLENPADDED(a) (STRLENS(a,0) STRLENS(a,1) STRLENS(a,2) STRLENS(a,3) STRLENS(a,4) STRLENS(a,5) STRLENS(a,6) STRLENS(a,7) STRLENS(a,8) STRLENS(a,9) -1)
#define STRLEN(a) STRLENPADDED((a "\0\0\0\0\0\0\0\0\0")) // padding required to prevent 'index out of range' issues.
这个STRLEN宏将为您提供您提供它的字符串文字的长度,只要它长度少于10个字符。在我的情况下,这已经足够了,但在OP的情况下,宏可能需要扩展(很多)。由于它是高度重复的,您可以轻松编写脚本来创建一个接受1000个字符的宏。
PS:这只是我真正想要解决的问题的一个简单分支,这是一个静态计算字符串的HASH值,所以我不需要在我的嵌入式系统中使用任何字符串。如果有人感兴趣(它会节省我一天的搜索和解决),这将在一个小字符串文字上做一个FNV哈希,可以优化成一个分配:
#ifdef _MSC_BUILD
#define HASH_FNV_OFFSET_BASIS 0x811c9dc5ULL
#define HASH_TYPE int
#else // properly define for your own compiler to get rid of overflow warnings
#define HASH_FNV_OFFSET_BASIS 0x811c9dc5UL
#define HASH_TYPE int
#endif
#define HASH_FNV_PRIME 16777619
#define HASH0(a) (a[0] ? ((HASH_TYPE)(HASH_FNV_OFFSET_BASIS * HASH_FNV_PRIME)^(HASH_TYPE)a[0]) : HASH_FNV_OFFSET_BASIS)
#define HASH2(a,i,b) ((b * (a[i] ? HASH_FNV_PRIME : 1))^(HASH_TYPE)(a[i] ? a[i] : 0))
#define HASHPADDED(a) HASH2(a,9,HASH2(a,8,HASH2(a,7,HASH2(a,6,HASH2(a,5,HASH2(a,4,HASH2(a,3,HASH2(a,2,HASH2(a,1,HASH0(a))))))))))
#define HASH(a) HASHPADDED((a "\0\0\0\0\0\0\0\0\0"))