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; 

如果节点没有子节点,例如上例中的x3.14 ,则其opgxhxNULL ,否则其fxNULL

我计算导数的函数看起来像

 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::stringstd::wstring对象在C ++中干净地执行此operator+() ,这些对象具有正确的operator+()

或者,您可以使用适当的面向对象的API实现自己的字符串结构。