C是否有任何添加字符串的工具?
我正在创建一个函数,它返回一个表示为树的函数的导数
/ + \ * ^ / \ / \ x 5 3.14 x
与表单的节点
typedef struct node { char * fx; // function struct node * gx; // left-hand side char * op; // operator struct node * hx; // right-hand side } node;
如果节点没有子节点,例如上例中的x
, 3.14
,则其op
, gx
和hx
为NULL
,否则其fx
为NULL
。
我计算导数的函数看起来像
char * deriveFromTree ( node * rt ) { char * buff = malloc(100*sizeof(char)); int curBuffIdx = 0; if (rt->op) // if rt is of the form rt = gx op hx { char * dgdx = deriveFromTree(rt->gx); // g'(x) char * dhdx = deriveFromTree(rt->hx); // h'(x) char thisop = *rt->op; if (thisop == '+' || thisop == '-') { // ... want to do equivalent of // buff = dgdx + thisop + dhdx } else if (thisop == '*') { // ... } else if (thisop == '/') { // ... } else if (thisop == '^') { // ... } } else // rt is a base expression -- x or a constant { buff[curBuffIdx] = strcmp(rt->fx, 'x') ? '1': '0'; } buff[++curBuffIdx] = '\0'; return buff; }
但我在所有的弦乐添加上都被绊倒了。 如果已经有一种紧凑的方式,我可以从零开始创建一个字符串加法器
// ... want to do equivalent of // buff = dgdx + thisop + dhdx
然后我想使用那个工具。
如果你的C标准库是GNU或* BSD,那么你可能有asprintf
。 但是,您可能需要启用function测试宏才能使用它。 如果您没有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; }
这是我所知道的在其他语言中串联连接运算符的最简洁的等价物。 (它不一定是执行时间最有效的,但它可能在程序员时间。)
您正在寻找的是字符串连接,标准C库函数是strcat
,或更好(因为可以说更安全) strncat
。
见http://linux.die.net/man/3/strcat
你想要实现的目标不能在普通的C中完成,因为它没有运算符重载。 您可以使用strncat
,但请注意,这是一个非常低级的解决方案,需要您手动管理内存。
您可以使用std::string
或std::wstring
对象在C ++中干净地执行此operator+()
,这些对象具有正确的operator+()
。
或者,您可以使用适当的面向对象的API实现自己的字符串结构。