gpt4 book ai didi

我可以静态分配这个字符串吗?如何?

转载 作者:太空宇宙 更新时间:2023-11-04 01:48:34 25 4
gpt4 key购买 nike

我一直不确定这样做的正确方法。我正在尝试编写以下函数

int obtain_substr(int seqn, char *fullstring, int position, char **ret_string);

我希望它从 fullstringpositionth char 获取定义的 STRSIZE 的子字符串,在前面加上seqn 到输出字符串(即 *ret_string)。

例如,如果我有以下值:

#define STRSIZE 7
seqn = 2;
fullstring = "Lorem ipsum dolor sit amet."
position = 3;

我希望 obtain_substr 返回以下值:

*ret_string = "2em ipsu";

到目前为止我一直在做的是以下功能,但老实说我不确定它的实现:

int obtain_substr(int seqn, char *fullstring, int position, char **ret_string) {
char *buf = malloc(sizeof(char) * STRSIZE);
memset((void *) buf, 0, sizeof(char) * STRSIZE);
if (buf == NULL) {
perror("malloc");
return -1;
}
buf = strncpy(buf, fullstring + position, STRSIZE); // Obtain substring
sprintf(*ret_string, "%d%s", seqn, buf); // Merge sequence number and substring
return 0;
}

我是否忘记管理一些以 \0 结尾的字符串?由于我确切地知道输出字符串的大小,我可以静态地声明它吗?如果是,我应该如何编辑我的代码?我想每次都使用 mallocmemset,知道子字符串的大小正好是 STRSIZE + 1(可能是 +2 for the \0?) 可能不是最优的。

最佳答案

Malloc 与普通数组

是的,您可以使用具有自动存储期限的数组。如果您使用 static 声明它,在大多数实现中它不会被放置在堆栈中。但由于 STRSIZE 如此之小,我认为堆栈溢出的可能性不大。

你也可以使用初始化器来避免memset

int obtain_substr(int seqn, char *fullstring, int position, char **ret_string) {
char buf[STRSIZE + 1] = {0}; // +1 for \0
strncpy(buf, fullstring + position, STRSIZE);
sprintf(*ret_string, "%d%s", seqn, buf);
return 0;
}

Strncpy 是垃圾

如果字符串的大小正好是 STRSIZE

strncpy 将不会正确终止字符串。您必须手动终止字符串才能确定。

int obtain_substr(int seqn, char *fullstring, int position, char **ret_string) {
char buf[STRSIZE + 1] = {0}; // +1 for \0
strncpy(buf, fullstring + position, STRSIZE);
buf[STRSIZE] = 0;
sprintf(*ret_string, "%d%s", seqn, buf);
return 0;
}

严格来说这不是必需的,因为我们将 buf 初始化为全零,并且最后一个元素未被 strncpy 修改。但是这种东西在编辑函数的时候很容易坏掉。明确说明它并没有坏处。

改进

您实际上不需要临时缓冲区:您可以使用 snprintf 精度参数限制复制字符串的大小,其中 %s 是最大限制。

每个编辑字符串的字符串函数,也应该接收可用空间的大小以避免溢出。 (您应该尽可能使用 snprintf 而不是 sprintf。)似乎也没有理由将 ret_string 设为双指针。

fullstring 也应声明为 const,因为它未被此函数修改。

int obtain_substr(int seqn, char const *fullstring, size_t position, char *ret_string, size_t ret_size) {
snprintf(ret_string, ret_size, "%d%.*s", seqn, STRSIZE, fullstring + position);
return 0;
}

你可以这样调用它:

#define SIZE 16
char str[SIZE];
obtain_substr(2, "Lorem ipsum dolor sit amet.", 3, str, SIZE);

关于我可以静态分配这个字符串吗?如何?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48376749/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com