C 是否有任何工具可以进行字符串加法? [英] Does C have any tools for doing string addition?

查看:23
本文介绍了C 是否有任何工具可以进行字符串加法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在制作一个函数,该函数返回一个函数的导数,该函数表示为一棵树

I'm making a function that returns the derivative of a function that is represented as a tree like

      /   +    
     *          ^
   /         /   
  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;

如果一个节点没有子节点,例如上面例子中的x53.14,那么它的opgxhxNULL,否则它的 fxNULL.

If a node has no children, e.g. x, 5, 3.14 in the above example, then its op, gx and hx are NULL, and otherwise its fx is NULL.

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

My function for calculating the derivative looks like

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] = '';
    return buff;
}

但是我对所有的字符串添加感到困惑.我可以从头开始创建一个字符串加法器,如果已经有一种紧凑的方式来做

but I'm getting tripped up on all the string addition. I could create from scratch a string adder, if there's already a compact way of doing

            // ... want to do equivalent of
            //     buff = dgdx + thisop + dhdx

那么我想使用那个工具.

then I'd like to use that tool.

推荐答案

如果您的 C 标准库是 GNU 或 *BSD,那么您可能有 asprintf 可用.不过,您可能需要启用功能测试宏才能使用它.如果您没有 asprintf 可用,可以很容易地根据 C 标准 vsnprintf 函数定义它.

If your C standard library is GNU or *BSD, then you probably have asprintf available. You may need to enable a feature test macro to use it, though. If you don't have asprintf available, it can easily be defined in terms of the C standard vsnprintf function.

asprintf 将格式的结果作为新分配的字符串返回(您负责free).所以你可以写,例如:

asprintf returns the result of the format as a newly-allocated string (which it is your responsibility to free). So you could write, for example:

char* buff;
int n = asprintf(&buff, "%s%c%s", dgdx, thisop, dhdx);

我通常使用包装函数,它返回字符串而不是长度,所以你可以这样写:

I usually use a wrapper function, which returns the string rather than the length, so you can write:

char* buff = concatf("%s%c%s", dgdx, thisop, dhdx);

这里是三个简单的实现;第一个将在带有 vasprintf 的系统上工作;带有 Posix vsnprintf 的系统上的第二个;第三个用于 Windows,它显然实现了不同的 snprintf 接口.

Here are three simple implementations; the first will work on systems with vasprintf; the second on systems with Posix vsnprintf; and the third for Windows, which apparently implements a different snprintf interface.

// 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;
}

这是我所知道的与其他语言中的字符串连接运算符最简洁的等价物.(它不一定在执行时间上最有效,但在程序员时间里可能是最有效的.)

That's the most concise equivalent I know of to string concatenation operators in other languages. (It's not necessarily the most efficient in execution time, but it probably is in programmer time.)

这篇关于C 是否有任何工具可以进行字符串加法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆