使用纯 C(和 C 预处理器)我想创建一个包含长度参数的字符串缓冲区,这样我就可以轻松地传递它,并且任何对其进行操作的函数都可以这样做而不会有写过去的危险结束。这很简单:
typedef struct strbuf_t_ {
int length;
char str[1];
} strbuf_t;
但是如果我想在堆栈上有一个小的暂存空间来格式化一些输出文本,那么在堆栈上分配一个 strbuf_t
是很简单的方法。我想要的是一些允许我做的聪明的宏:
STRBUF(10) foo;
printf("foo.length = %d\n", foo.length); // outputs: foo.length = 10
strncpy(foo.str, "this is too long", foo.length);
不幸的是,我似乎无法做到这一点。我想到的最好的是:
#define STRBUF(size, name) \
struct {\
strbuf_t buf;\
char space[size - 1];\
char zero;\
} name ## _plus_space_ = { .buf={.length=size}, .space="", .zero='\0'};\
strbuf_t *name = &name ## _plus_space_.buf
int main(void)
{
STRBUF(10, a);
strncpy(a->str, "Hello, world!", a->length);
printf("a->length = %d\n", a->length); // outputs: a->length = 10
puts(a->str); // outputs: Hello, wor
}
这满足了我列出的所有要求,但是a
是一个指针而不是结构本身,分配肯定不直观。
有没有人想出更好的东西?
最佳答案
我认为您已经非常接近解决方案了。只需在您的结构中保留一个 char*
并通过字符数组分配它。为了在字符串末尾保存尾随零,只需分配一个额外的字符到大小并用零初始化整个数组。
typedef struct
{
int length;
char* str;
} strbuf_t;
#define STRBUF(varname, size) \
char _buffer_ ## varname[size + 1] = {'\0'}; \
strbuf_t varname = { size, _buffer_ ## varname }
int main()
{
STRBUF(a, 10);
strncpy(a.str, "Hello, world!", a.length);
printf("a.length = %d\n", a.length);
puts(a.str);
}
关于c - 在堆栈上分配大小的字符串缓冲区的好方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34185799/