c - 在堆栈上分配大小的字符串缓冲区的好方法是什么?

标签 c

使用纯 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/

相关文章:

c - 在 if 指令中读取 c 中的字符串

c - 替换极其缓慢的 pow() 函数

C - malloc 字符串时出错

c - for循环中的动态内存分配

c - 用于无括号、空格敏感的 C 语法的工具

c++ - 将字符串转换为函数

c - OpenCV 中的差异图像

c - 在 C 中使用带有 ZBar 的 OpenCV 的问题

c - 使用 MPI_Isend 和 MPI_Irecv 而不是 MPI_Bcast 为所有处理器定时广播消息

c - 无法在 C 中将 'y1' 用作浮点变量