char str1[size];
即使您正确计算了尺寸,我还是建议您使用
char * str = malloc(size);
无论哪种方式,在您以一种或另一种方式获得字符串所需的内存后,您都必须先初始化它
str[0]=0;
如果您打算使用strcat。
for (int i = 0; i < a; i+=1) {
strcat(str1, "\x90");
}
这很有用,如果 "\x90" 实际上是一个字符串(即由多个字符组成的东西)并且该字符串是短(很难给出一个硬边框,但大约 16 字节的东西是顶部)和 a 相当小[1]。在这里,正如John Coleman 已经建议的那样,memset 是一种更好的方法。
memset(str, '\x90', a);
因为您知道应该存储"blablabla" 的位置,所以只需使用strcpy 而不是strcat 将其存储在那里
// strcat(str1, "blablabla");
strcpy(str + a, "blablabla");
但是,您需要"blablabla" 之后的字符的地址(一种或另一种方式)。所以我什至不会那样做,而是这样:
const char * add_str = "blablabla";
size_t sl = strlen(add_str);
memcpy(str + a, add_str, sl);
然后,不要使用第二个循环,而是使用另一个 memset:
memset(str + a + sl, '\x90', b);
最后但同样重要的是,strcpy 比 strcat 更好(这里,memcpy 没有帮助):
strcpy(str + a + sl + b, "h\xef\xff\xbf");
但是你在开始时需要它的大小来计算大小,所以最好还是像 blablabla 字符串那样做(记住拖尾 '\0')。
最后,我会将所有这些代码放入这样的函数中:
char * gen_string(int a, int b) {
const char * add_str_1 = "blablabla";
size_t sl_1 = strlen(add_str_1);
const char * add_str_2 = "h\xef\xff\xbf";
size_t sl_2 = strlen(add_str_2);
size_t size = a + sl_1 + b + sl_2 + 1;
// The + 1 is important for the '\0' at the end
char * str = malloc(size);
if (!str) {
return NULL;
}
memset(str, '\x90', a);
memcpy(str + a, add_str_1, sl_1);
memset(str + a + sl_1, '\x90', b);
memcpy(str + a + sl_1 + b, add_str_2, sl_2);
str[a + sl_1 + b + sl_2] = 0; // 0 is the same as '\0'
return str;
}
记住free() gen_string 在某个时候的返回值。
如果memset 和memcpy 调用的列表变得更长,那么我建议这样做:
char * ptr = str;
memset(ptr, '\x90', a ); ptr += a;
memcpy(ptr, add_str_1, sl_1); ptr += sl_1;
memset(ptr, '\x90', b ); ptr += b;
memcpy(ptr, add_str_2, sl_2); ptr += sl_2;
*ptr = 0; // 0 is the same as '\0'
甚至可以为memset 和memcpy 创建一个宏:
#define MEMSET(c, l) do { memset(ptr, c, l); ptr += l; } while (0)
#define MEMCPY(s, l) do { memcpy(ptr, s, l); ptr += l; } while (0)
char * ptr = str;
MEMSET('\x90', a );
MEMCPY(add_str_1, sl_1);
MEMSET('\x90', b );
MEMCPY(add_str_2, sl_2);
*ptr = 0; // 0 is the same as '\0'
#undef MEMSET
#undef MEMCPY
关于为什么要按照我推荐的方式进行操作的理由,我建议您阅读博客文章 Back to Basics(由 Stack Overflow 的一位创始人撰写),这不仅是 John Coleman 最喜欢的博客文章,也是我最喜欢的博客文章.在那里您将了解到,在循环中使用 strcat 就像您第一次尝试它的方式一样具有二次运行时间,因此,为什么不按照您的方式使用它。
[1] 如果a 很大和/或需要重复的字符串很长,更好的解决方案是这样的:
const char * str_a = "\x90";
size_t sl_a = strlen(str_a);
char * ptr = str;
for (size_t i = 0; i < a; ++i) {
strcpy(ptr, str_a);
ptr += sl_a;
}
// then go on at address str + a * sl_a