C...更好的插入字符串的方法?
C...better way of inserting in a string?
我想将一个可变字符串插入到一个预先确定的字符串中....这是我目前所拥有内容的简化版本(我省略了错误检查等):
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
变量。
(最初我认为我可以做到这一点,然后重新分配..即 char cmd[50] = "CREATE... "
或 char *cmd = "CREATE..."
,但是 realloc
只适用于以前 malloc
'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);
}
EDIT(回应评论):sizeof(char) => 1
,+1 终止 [=12=]
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
是 "pre-determined" 字符串的长度,path
是您在函数中作为参数获取的可变字符串。最后,cmd
应该包含预先确定的文本,路径代替 %s
。
为什么不呢?:
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, ");");
}
为什么不忘记 malloc
从而避免代码中的内存泄漏?
即
size_t len = 55 + strlen(path);
char cmd[len];
然后使用
snprintf(cmd, len, "CREATE VIRTUAL TABLE temp.tablename USING CSVFILE(%s);", path);
忽略手动创建未经处理的 SQL 语句的不明智行为,您可以正确使用 sprintf
函数。参数是 output
、format
、args
。例如:
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
永远不会被修改,因此可以声明为 static
和 const
。如果您只是将两个字符串的长度相加,则输出缓冲区可以保证足够长。另外,请记住,如果您需要在函数外部使用新字符串的值,则必须以某种方式 return 指针。在您的示例中,您调用 realloc
,但永远不要让调用者知道内存块已更改。这通常会导致段错误,因为 realloc
在扩展内存时可能会或可能不会更改内存的位置。
有什么问题
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);
}
我想将一个可变字符串插入到一个预先确定的字符串中....这是我目前所拥有内容的简化版本(我省略了错误检查等):
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
变量。
(最初我认为我可以做到这一点,然后重新分配..即 char cmd[50] = "CREATE... "
或 char *cmd = "CREATE..."
,但是 realloc
只适用于以前 malloc
'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);
}
EDIT(回应评论):sizeof(char) => 1
,+1 终止 [=12=]
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
是 "pre-determined" 字符串的长度,path
是您在函数中作为参数获取的可变字符串。最后,cmd
应该包含预先确定的文本,路径代替 %s
。
为什么不呢?:
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, ");");
}
为什么不忘记 malloc
从而避免代码中的内存泄漏?
即
size_t len = 55 + strlen(path);
char cmd[len];
然后使用
snprintf(cmd, len, "CREATE VIRTUAL TABLE temp.tablename USING CSVFILE(%s);", path);
忽略手动创建未经处理的 SQL 语句的不明智行为,您可以正确使用 sprintf
函数。参数是 output
、format
、args
。例如:
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
永远不会被修改,因此可以声明为 static
和 const
。如果您只是将两个字符串的长度相加,则输出缓冲区可以保证足够长。另外,请记住,如果您需要在函数外部使用新字符串的值,则必须以某种方式 return 指针。在您的示例中,您调用 realloc
,但永远不要让调用者知道内存块已更改。这通常会导致段错误,因为 realloc
在扩展内存时可能会或可能不会更改内存的位置。
有什么问题
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);
}