当前位置: 首页 > 面试题库 >

C是否有任何用于进行字符串加法的工具?

刘博文
2023-03-14
问题内容

我正在做一个函数,该函数返回表示为树的函数的派生类,例如

      /   +    \
     *          ^
   /   \      /   \
  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在上述例子中,那么它的opgx并且hxNULL,否则其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可以使用。但是,您可能需要启用功能测试宏才能使用它。如果没有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;
}

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



 类似资料:
  • 所以我应该创建一个方法来检查字符串是否包含任何数字。如果有,它将返回“yes”,如果没有,它将返回“no”。到目前为止,我认为我已经做了所有正确的事情,但不确定如何使用indexOf()搜索0-9之间的任何数字。请注意,我是javascript的初学者,所以我将感谢初学者友好的回复。

  • 问题内容: 我在寻找Python中的方法。 我想要做: 问题答案: 你可以使用in运算符:

  • 问题内容: 如何测试字符串以查看其是否包含数组中的任何字符串? 而不是使用 问题答案: 编辑:这是使用Java 8流API的更新。如此清洁。仍然可以与正则表达式结合使用。 另外,如果我们将输入类型更改为List而不是数组,则可以使用。 如果希望返回匹配的字符串,也可以使用。 原始的过时的答案: 这是(VERY BASIC)静态方法。请注意,在比较字符串上区分大小写。一个原始的,使其不区分大小写的办

  • 显然,constexpr std::string尚未添加到GCC的libstdc中(从GCC v11.2开始)。 此代码: 不编译: 我的问题是,当一个字符串包含超过16s(因为GCC的SSO缓冲区大小是16)时,这些字符串将如何在引擎盖下工作?有人能给我简单解释一下吗?一个简单的构造函数会在堆栈上创建字符串对象而不使用动态分配吗? 此代码: 打印这个: 现在通过在这里使用(显然不使用GCC v1

  • 我正在使用folowing逻辑来检查接收到的字符串是否为有效数字 我将在一个高度多线程的环境中使用它,在这个环境中一次可以有800-900个并发用户,请让我知道,如果这个代码有任何循环漏洞或没有? 请分享您的观点 提前致谢

  • 我是Kotlin的新手(我有Java背景),我似乎不知道如何检查字符串是否包含关键字列表中的匹配项。 我想做的是检查一个字符串是否包含一个关键字数组的匹配(请不区分大小写)。如果是,则打印出匹配的关键字和包含该关键字的字符串。(我将循环访问一个文件中的一串字符串)。 这里有一个MVE供初学者使用: 作为一个开始(这忽略了'match'变量和getting-a-list-of-keywords-ma

  • 我想过滤掉列表中所有列的值为零的行。 这是我尝试过的, 这对于小型数据集很好,但是如果col_list很长,则会出现以下错误。 ava.lang.stackoverflowerrorat org.apache.spark.sql.catalyst.analysis.resolvelambdavariables.org$Apache$spark$sql$catalys$analysis$resolv

  • 本文向大家介绍C#验证给定字符串是否为数字的方法,包括了C#验证给定字符串是否为数字的方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了C#验证给定字符串是否为数字的方法。分享给大家供大家参考。具体分析如下: 这段C#代码用于验证给定的字符串是否为数字,不能用于验证负数,字符串中只能出现数字和小数点,否则认为不是数字,不验证数字的长度,也就是说,给定的字符串再长,哪怕是1万个字符,也可以