如果您的 C 标准库是 GNU 或 *BSD,那么您可能有asprintf
可用的。不过,您可能需要启用功能测试宏才能使用它。如果你没有asprintf
可用,它可以很容易地根据 C 标准定义vsnprintf
功能。
asprintf
将格式的结果作为新分配的字符串返回(您有责任free
)。所以你可以写,例如:
char* buff;
int n = asprintf(&buff, "%s%c%s", dgdx, thisop, dhdx);
我通常使用包装函数,它返回字符串而不是长度,因此您可以编写:
char* buff = concatf("%s%c%s", dgdx, thisop, dhdx);
这是三个简单的实现;第一个将在系统上运行vasprintf
;第二个在 Posix 系统上vsnprintf
;第三个针对 Windows,它显然实现了不同的snprintf
界面。
// Version 1, systems which have vasprintf:
char* concatf(const char* fmt, ...) {
va_list args;
char* buf = NULL;
va_start(args, fmt);
int n = vasprintf(&buf, fmt, args);
va_end(args);
if (n < 0) { free(buf); buf = NULL; }
return buf;
}
// Version 2: Systems without vasprintf but with vsnprintf
char* concatf(const char* fmt, ...) {
va_list args;
va_start(args, fmt);
char* buf = NULL;
int n = vsnprintf(NULL, 0, fmt, args);
va_end(args);
if (n >= 0) {
va_start(args, fmt);
buf = malloc(n+1);
if (buf) vsnprintf(buf, n+1, fmt, args);
va_end(args);
}
return buf;
}
// Version 3: Windows
// Apparently, the implementation of vsnprintf on Windows returns -1
// if not enough space has been provided. So here is the above code
// rewritten according to the documentation I found in
// https://msdn.microsoft.com/en-us/library/w05tbk72%28VS.71%29.aspx
// and
// https://msdn.microsoft.com/en-us/library/1kt27hek%28v=vs.71%29.aspx
// but totally untested. (If you try it, let me know)
char* concatf(const char* fmt, ...) {
char* buf = NULL;
va_list args;
va_start(args, fmt);
int n = _vscprintf(fmt, args);
va_end(args);
if (n >= 0) {
va_start(args, fmt);
buf = malloc(n+1);
if (buf) _vsnprintf(buf, n+1, fmt, args);
va_end(args);
}
return buf;
}
这是我所知道的与其他语言中的字符串连接运算符最简洁的等价形式。 (它不一定是执行时间上最有效的,但它可能是程序员时间上最有效的。)