有没有一种方法可以在不预先分配缓冲区的情况下连接字符串?
请考虑以下事项:
int main()
{
char buf1[] = "world!";
char buf2[100] = "hello ";
char * p = "hello ";
// printf("%s", strcat(p, buf1)); // UB
printf("%s", strcat(buf2, buf1)); // correct way to use strcat
return 0;
}
如果我有一个我想要作为字符串前缀的指针,我必须首先将其复制到缓冲区然后strcat()
吗?是否有任何功能隐含地这样做?
我想到的唯一选项是strcat()
和sprintf()
,两者都需要缓冲区。
str1 + str2
语法的东西答案 0 :(得分:6)
嗯,它不是标准的C,所以不太便携,但在GNU libc系统上你可以使用asprintf()
。
int main(void)
{
const char buf1[] = "world!";
const char * const p = "hello ";
char *s;
if (asprintf(&s, "%s%s", p, buf1) > 0 && s != NULL)
{
puts(s);
free(s);
}
return 0;
}
在兼容系统上编译和运行时,会打印
hello world!
答案 1 :(得分:4)
我真的想要使用C,那么你需要使用缓冲区。在C ++或Python中,您可以使用构造函数和运算符来隐藏工作,但在C语言中,您必须自己做事。如果你想让你的代码更容易,你可以创建一个小帮助函数,但要注意内存泄漏和线程:
const char *
只要结果字符串不超过2048个字符,此示例就会起作用;否则结果字符串将被截断。
这当然只是您可以创建的辅助函数的一个示例。
请注意,上面的示例返回了您无法编辑的SetCurrentValue(DistanceTextProperty,
Math.Round((To - From).Length, 1).ToString(CultureInfo.InvariantCulture));
。如果你想进一步编辑字符串,你需要创建一个辅助函数来分配一个缓冲区,但是你需要管理你的内存!
答案 2 :(得分:3)
在运行时执行此操作的最有效方法是调用malloc并为新字符串分配空间,然后将所有内容复制到那里。这很可能是Python在行后面所做的 - 虽然它将有一个字符串类型。
在ADT /类之外执行此操作的缺点是您必须手动进行清理。
然而,使用malloc + copy远比任何* printf快,它是线程安全的,并且可以再次重复使用相同的函数。例如:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char* strdog (const char* s1, const char* s2)
{
size_t size1 = strlen(s1);
size_t size2 = strlen(s2);
char* result = malloc(size1 + size2 + 1);
if(result == NULL)
{
exit(EXIT_FAILURE);
}
memcpy(result, s1, size1);
memcpy(result+size1, s2, size2);
result[size1 + size2] = '\0';
return result;
}
inline void cleandog (char* s)
{
free(s);
}
int main (void)
{
char s1[] = "hello ";
char s2[] = "world";
char* str = strdog(s1, s2);
puts(str);
cleandog(str);
}
但请注意,C支持编译时连接。因此,如果您只使用字符串文字,则应该执行以下操作:
#define HELLO "hello "
#define WORLD "world"
...
const char* str = HELLO WORLD;
puts(str);
这当然是它们的优越版本,但仅适用于编译时字符串文字。