C中字符串连接的代码太多
我的代码中有很多strcat行。有没有更好的方法在C中连接字符串C中字符串连接的代码太多,c,string,C,String,我的代码中有很多strcat行。有没有更好的方法在C中连接字符串 char material[50]; // it is defined before this code. char result[10000]; strcpy(result, "// Assign new material to worldGlobe\n"); strcat(result, "shadingNode -asShader lambert -n "); strcat(result, material); strcat
char material[50]; // it is defined before this code.
char result[10000];
strcpy(result, "// Assign new material to worldGlobe\n");
strcat(result, "shadingNode -asShader lambert -n ");
strcat(result, material);
strcat(result, ";\n");
那怎么办
sprintf(result, "// Assign new material to worldGlobe\nshadingNode -asShader lambert -n %s;\n\0", material);
那怎么办
sprintf(result, "// Assign new material to worldGlobe\nshadingNode -asShader lambert -n %s;\n\0", material);
您可以将格式字符串与(safe与
sprintf()
)结合使用:
您可以将格式字符串与(safe与
sprintf()
)结合使用:
C语言主要是一种自己动手的语言 既然您已经知道如何压缩字符串,那么您应该编写自己的函数以使其更简单 我的建议是:
char* str_multicat(char* result, ...);
str_mutlicat(result, "// Assign new material to worldGlobe\n",
"shadingNode -asShader lambert -n ",
material,
";\n",
NULL);
并称之为:
char* str_multicat(char* result, ...);
str_mutlicat(result, "// Assign new material to worldGlobe\n",
"shadingNode -asShader lambert -n ",
material,
";\n",
NULL);
(提示,如果您不知道
…
语法,请查看va_arg
,va_start
,va_end
)C主要是一种自己动手的语言
既然您已经知道如何压缩字符串,那么您应该编写自己的函数以使其更简单
我的建议是:
char* str_multicat(char* result, ...);
str_mutlicat(result, "// Assign new material to worldGlobe\n",
"shadingNode -asShader lambert -n ",
material,
";\n",
NULL);
并称之为:
char* str_multicat(char* result, ...);
str_mutlicat(result, "// Assign new material to worldGlobe\n",
"shadingNode -asShader lambert -n ",
material,
";\n",
NULL);
(提示,如果您不知道
…
语法,请查看va_arg
,va_start
,va_end
)strcat
仅适用于非常小的字符串;对于任何非琐碎的事情,它都有几个问题,例如:
- 由于这个问题,
在输入字符串的长度上是O(n),也就是说,字符串越长,每次连接所需的时间就越长。这是因为strcat必须遍历整个字符串才能找到其结尾。要解决这个问题,请将字符串的长度与字符串数据一起存储,这将允许您直接跳到字符串的末尾strcat
- 它不做任何边界检查。如果你
在字符串的末尾写得太多,它会很高兴地写过字符串的末尾,在最好的情况下会产生一个segfault,在最坏的情况下会产生一个严重的安全漏洞,并且很可能会出现一些让你头痛的bugstrcat
部分解决了此问题,只要您将正确大小的目标缓冲区传递给它即可strncat
- 如果目标缓冲区太小,则无论是
还是strcat
都不会增加其大小:您必须自己进行此操作strncat
b) 将字符串直接写入流。输出的内容看起来很像代码——为什么不直接写入文件?
strcat
只适用于非常小的字符串;对于任何非琐碎的事情,它都有几个问题,例如:
- 由于这个问题,
在输入字符串的长度上是O(n),也就是说,字符串越长,每次连接所需的时间就越长。这是因为strcat必须遍历整个字符串才能找到其结尾。要解决这个问题,请将字符串的长度与字符串数据一起存储,这将允许您直接跳到字符串的末尾strcat
- 它不做任何边界检查。如果你
在字符串的末尾写得太多,它会很高兴地写过字符串的末尾,在最好的情况下会产生一个segfault,在最坏的情况下会产生一个严重的安全漏洞,并且很可能会出现一些让你头痛的bugstrcat
部分解决了此问题,只要您将正确大小的目标缓冲区传递给它即可strncat
- 如果目标缓冲区太小,则无论是
还是strcat
都不会增加其大小:您必须自己进行此操作strncat
b) 将字符串直接写入流。输出的内容看起来很像代码—为什么不直接将其写入文件?您可以使用一个函数返回指向字符串结尾的指针,并在以后的调用中使用该结尾指针。这将消除一堆额外的“首先,找到字符串的结尾”的东西 使用类似于:
char result[10000];
char *end = &result[0];
result[0] = '\0'; // not strictly necessary if you cat a string, but why not
end = faster_cat(end, "// Assign new material to worldGlobe\n");
end = faster_cat(end, "shadingNode -asShader lambert -n ");
end = faster_cat(end, material);
end = faster_cat(end, ";\n");
// result now contains the whole catted string
您可以使用一个函数返回指向字符串结尾的指针,并在以后的调用中使用该结尾指针。这将消除一堆额外的“首先,找到字符串的结尾”的东西 使用类似于:
char result[10000];
char *end = &result[0];
result[0] = '\0'; // not strictly necessary if you cat a string, but why not
end = faster_cat(end, "// Assign new material to worldGlobe\n");
end = faster_cat(end, "shadingNode -asShader lambert -n ");
end = faster_cat(end, material);
end = faster_cat(end, ";\n");
// result now contains the whole catted string
构建一个字符串缓冲区结构,它将跟踪缓冲区中的当前位置,并将其与
vsprintf
相结合,得到一个catf()
。函数vsnprintf()
(假设它可用)与printf
类似,只是它在格式字符串后采用va_列表
,而不是…
与其他答案相比,这种方法的优势在于,它允许您从代码中任何可以访问结构的地方“cat”,而无需显式地携带当前长度,也无需像strcat那样每次都重新计算
这是一张免费的草图
/* Note: the typedef is for the pointer, not the struct. */
typedef struct StrBufStruct {
char * buffer,
size_t size,
size_t pos
} * StrBuf;
/* Create a new StrBuf. NOTE: Could statically allocate too. */
StrBuf newStrBuf(size_t size){
StrBuf sb;
sb = malloc( sizeof(struct StrBufStruct) );
sb->size = size;
sb->pos = 0;
sb->buffer = malloc( size );
/* TODO: ALWAYS CHECK YOUR MALLOC!!! */
}
int sbcatf( StrBuf b, char * fmt, ... )
{
va_list ap;
int res;
if( b->pos < b->size )
{
va_start(ap,fmt);
res = vsnprintf( b->buffer[b->pos], b->size - b->pos, fmt, ap );
b->pos += res;
va_end();
} else {
/* If you want to get really fancy, use realloc so you don't have to worry
about buffer size at all. But be careful, you can run out of memory. */
}
}
/* TODO: Write a free/delete function */
int main(int argc, char **argv){
int i;
/* initialize your structure */
StrBuf sb = newStrBuf(10000);
/* concatenate numbers 0-999 */
for(i=0; i < 1000; i++){
sbcatf(sb, "I=%d\n", i);
}
/* TODO: whatever needs to be done with sb->buffer */
/* free your structure */
deleteStrBuf(sb);
}
构建一个字符串缓冲区结构,它将跟踪缓冲区中的当前位置,并将其与
vsprintf
相结合,得到一个catf()
。函数vsn