在C中,如何确保初始化字符串的长度小于指定值

问题描述:

我有一个struct,其中成员是最大长度为N的字符串。定义:在C中,如何确保初始化字符串的长度小于指定值

typedef struct 
{ 
    const char foo[N]; 
} bar_t; 

我希望这种结构的用户到foo成员以不超过N的长度初始化:

bar_t mybar = { .foo = "12345678" }; 

其中N=8。由于我无法控制bar_t的所有初始化,因此如果bar_t.foo的长度大于N,我想依靠编译器生成警告/错误。

的问题是,以考虑终止字符(为了能使用bar_t.foo作为一个正常的字符串),我需要用长度指定bar_t.fooN+1

或者,我可以的bar_t.foo长度设置为当使用长度为> N的字符串进行初始化时,获得编译器警告,但是当使用期望结束符字符的函数时,我现在需要使用期望的字符串长度来明确(即使用strn*()函数家族,N作为最大长度参数)。

有没有办法让编译器限制初始化器的长度,并且还能够在不明确最大字符串长度的情况下处理该字段?

+0

怎么样了相反的策略:总是零字符添加到字符串字面但是你可以使用类似于下面的宏和静态断言提供编译时检查:'.foo =“12345678 \ 0”'? – chux

GCC不会警告有关字符串初始化程序比分配的内存更长,因为它是完全合法的。

#include <stdio.h> 

#define N 6 
typedef struct 
{ 
    const char foo[N]; 
} bar_t; 

#define INIT_FOO(var, initString) \ 
    _Static_assert(sizeof(initString) < N, "Bad length!"); \ 
    bar_t var = { .foo = initString }; 

INIT_FOO(mybar, "Good"); 
//INIT_FOO(mybar, "Baaaad"); 

int main(void) { 
    printf("%s\n", mybar.foo); 
    return 0; 
} 

看到它在行动上ideone

+0

*因为它是完全合法的*:well gcc确实也有警告有效但危险的构造,所以我会说它没有* yet *:)(AFAIK)。其他一些编译器可能有这样的警告选项。请注意,PC-lint具有以下信息(784):* Nul字符从字符串*中截断。 – ouah

+0

谢谢。 '_Static_assert()'可能是一个合理的方法。这会使开发人员使用该结构更麻烦一些。 – theorifice