【问题标题】:Ways to build string in c在c中构建字符串的方法
【发布时间】:2012-02-22 14:18:36
【问题描述】:

我在这里基于 4 个参数构建一个字符串并使用 system() 调用它,但我这样做的方式似乎有点混乱。有没有更正确的方法我应该这样做而不使用所有那些 strcat 和 str1-4?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[])
{

    char str1[40] = "sed -n 's/.*\\(";
    char str2[] = "\\)\\(.*\\)\\(";
    char str3[] = "\\).*/\\2/p' ";
    char str4[] = " > ";

    if (argc != 5)
    {
        fprintf (stderr, "Usage %s <LogFile> <token1> <token2> <DumpFile>\n",
                argv[0]);
                exit(EXIT_FAILURE);
    }

    strcat(str1, argv[2]);
    strcat(str1, str2);
    strcat(str1, argv[3]);
    strcat(str1, str3);
    strcat(str1, argv[1]);
    strcat(str1, str4);
    strcat(str1, argv[4]);

    system(str1);

    return 0;
}

【问题讨论】:

    标签: c strcat


    【解决方案1】:

    您的代码的一个问题是您没有检查参数是否适合 40 个字节。

    我可能会使用snprintf:

    snprintf(str, LENGTH, "sed -n 's/.*\\(%s...", argv[2]...);
    

    【讨论】:

    • 您指的是哪个标准?它在 C 标准的当前 (C2011) 和以前 (C99) 版本中都是标准的。唯一不标准的地方是 Windows,微软陷入时间扭曲,坚持只有 C89 是标准的,并在下划线后面隐藏更新的名称:_snprintf() 等。
    • @JonathanLeffler 出于某种原因,我认为它没有在 C99 中指定。我看是的。太棒了!
    【解决方案2】:

    这节省了重复 strcat() 的二次行为。 OTOH,如果你打电话给system(),那你就会迷失在噪音中。

    char str1[4096];
    char str0[] = "sed -n 's/.*\\(";
    
    sprintf(str1, "%s%s%s%s%s%s%s%s", str0, argv[2], str2, argv[3], str3, argv[1], str4, argv[4]);
    

    如果您担心缓冲区溢出,可以使用snprintf()(您应该这样做;str1 中的 40 个字节是不够的;您将 96 留在末尾,就像在 char str1[4096]; 中一样)。您可以检查返回值以查看写入了多少个字符。

    【讨论】:

    • “你把 96 放在最后”就值得 +1。 :-)
    【解决方案3】:

    总有sprintf 让您的生活更简单。确保如果您使用 sptrintf 缓冲区对于结果来说足够大。还有一个更安全的版本snprintf 会为您进行边界检查。

    【讨论】:

      【解决方案4】:

      唯一的问题是你可能会遇到缓冲区溢出(如果输入太长)。修复它,检查字符串的长度(使用strlen),并分配足够的内存来包含你想要的字符串。

      分配足够的内存后,您可以使用循环,或让sprintf 为您完成工作。

      【讨论】:

        【解决方案5】:

        str1 仅 40 字节长,您向其附加了太多数据。很可能会发生堆栈溢出。我会这样做:

        char buffer[1000]; // Choose a reasonable size
        snprintf(buffer, sizeof(buffer),
            "sed -n 's/.*\\(%s\\)\\(.*\\)\\(%s\\).*/\\2/p' %s > %s",
            argv[2], argv[3], argv[1], argv[4]);
        

        【讨论】:

          【解决方案6】:

          如果您希望代码处理任意长的参数,则需要使用 malloc 动态分配字符缓冲区。

          1. 创建一个局部变量来计算所需的总长度,并使用对strlen 的重复调用来计算该长度。
          2. 请致电malloc 记住为空终止符再添加一个字符。
          3. 多次使用strcpystrcat 来构建字符串。
          4. 致电system
          5. 致电free(如果您的进程即将终止,请不要打扰)。

          【讨论】:

            猜你喜欢
            • 2016-08-23
            • 1970-01-01
            • 2021-12-15
            • 2023-03-21
            • 1970-01-01
            • 2013-12-11
            • 1970-01-01
            • 2010-09-27
            相关资源
            最近更新 更多