C ...插入字符串的更好方法是什么?

时间:2015-10-29 14:04:59

标签: c string string-formatting

我想将一个变量字符串插入一个预先确定的字符串....这是我到目前为止的简化版本(我省略了错误检查等):

void insertPath(char *path)
{
    char *cmd;
    cmd = (char *)malloc(50);
    strcpy(cmd, "CREATE VIRTUAL TABLE temp.tablename USING CSVFILE(");

    int new_size = (strlen(cmd) + strlen(path) + 2);
    cmd = (char *)realloc(cmd, new_size);

    strcat(cmd, path);
    strcat(cmd, ");");

   // Do other stuff here and finally free(cmd);



}

有更好的方法吗?

不必使用malloc realloc会很高兴,但我不想以固定长度实例化cmd变量。

(最初我认为我可以这样做,然后realloc ..ie char cmd[50] = "CREATE... "char *cmd = "CREATE...",但realloc仅适用于之前为malloc&的变量#39; d)

我能想到的另一种方式(而且我不确定这是否有效)将是:

void insertPath(char *path)
{
    char *cmd;
    cmd = (char *)malloc(55);
    strcpy(cmd, "CREATE VIRTUAL TABLE temp.tablename USING CSVFILE( %s);");

    int new_size = (strlen(cmd) + strlen(path));
    cmd = (char *)realloc(cmd, new_size);

    sprintf(cmd, path);

   // Do other stuff here and finally free(cmd);
}

5 个答案:

答案 0 :(得分:4)

编辑(回复评论):sizeof(char) => 1,+ 1,用于终止\0

snprintf怎么样?

size_t size = baseSize + strlen(path) + 1;
char *cmd = malloc(size);
snprintf(cmd, size, "CREATE VIRTUAL TABLE temp.tablename USING CSVFILE(%s);", path);

这里,baseSize是“预定”字符串的长度,path是您在函数中作为参数获得的变量字符串。最后,cmd应包含预先确定的文字,其路径代替%s

答案 1 :(得分:2)

为什么不忘记malloc,从而避免代码中的内存泄漏?

size_t len = 55 + strlen(path);
char cmd[len];

然后使用

snprintf(cmd, len, "CREATE VIRTUAL TABLE temp.tablename USING CSVFILE(%s);", path);

答案 2 :(得分:1)

有什么问题
void insertPath(char *path)
{
  const char cmd[] = "CREATE VIRTUAL TABLE temp.tablename USING CSVFILE( %s);";
  int size = strlen(cmd) + strlen(path) + 1; // *sizeof(char) if it makes you happy
  char *newcmd = malloc( size );
  snprintf(newcmd, size, cmd, path);    
}

答案 3 :(得分:0)

为什么不呢?:

void insertPath(char *path) {
    char const *tmp = "CREATE VIRTUAL TABLE temp.tablename USING CSVFILE(";
    char       *cmd = (char*) malloc(strlen(path) + strlen(tmp) + 3);
    strcpy(cmd, tmp);
    strcat(cmd, path);
    strcat(cmd, ");");
}

答案 4 :(得分:0)

忽略手动创建未经过规范的SQL语句的不明智之处,您可以正确使用sprintf函数。参数为outputformatargs。例如:

char *insertPath(const char *path)
{
    static const char *cmd = "CREATE VIRTUAL TABLE temp.tablename USING CSVFILE(%s);";
    char *output = malloc(strlen(cmd) + strlen(path)); // Strictly this should be ... - 1 since it includes the the length of '%s'
    sprintf(output, cmd, path);
    return output;
}

尽量避免在不需要的情况下分配内存。此处,模板字符串cmd永远不会被修改,因此可以声明staticconst。如果只是将两个字符串的长度加在一起,输出缓冲区就足够长了。另外,请记住,如果需要在函数外部使用新字符串的值,则必须以某种方式返回指针。在您的示例中,您调用realloc,但绝不让调用者知道内存块已更改。这通常会导致段错误,因为realloc在扩展内存时可能会或可能不会更改内存的位置。