我从未确定这样做的正确方法。 我正在尝试编写以下函数
int obtain_substr(int seqn, char *fullstring, int position, char **ret_string);
我希望它从STRSIZE
的{{1}} position
获取定义char
的子字符串,将fullstring
添加到输出字符串(将会是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
和malloc
,知道子字符串的大小memset
(STRSIZE + 1
可能是+2
)可能是次优的。
答案 0 :(得分:3)
是的,您可以使用具有自动存储持续时间的阵列。如果用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
,则无法正确终止字符串。您必须手动终止字符串才能确定。
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);
答案 1 :(得分:0)
将seqn
从int
更改为char*
,然后您可以从
int obtain_substr(int seqn, char *fullstring, int position, char **ret_string);
到
char* obtain_substr(char* seqn, char *fullstring, int position);
然后执行类似
的操作// At this point, you know the length of the target string.
size_t seql=strlen(seqn);
int l=seql+STRSIZE,j,i;
char* ret_string=malloc((l+1)* sizeof *ret_string);
//+1 for the null character
if(NULL == ret_string)
exit(1); // Can't allocate memory
for(i=0;i<seql;i++)
ret_string[i]=seqn[i]; // Reads the sequence
for(i=seql,j=position;i<l;i++)
ret_string[i]=fullstring[j++] // Reads specified number of chars
ret_string[j]='\0'; // Important ! null terminate the string
return ret_string;