2016-11-29 52 views
0

我需要生成在C以下字符串:的Python生成的字符串用C

$(python -c "print('\x90' * a + 'blablabla' + '\x90' * b + 'h\xef\xff\xbf')") 

其中a和b是任意整数并且blablabla表示任意的字符串。我试图通过首先创建

char str1[size]; 

,然后做要做到这一点:

for (int i = 0; i < a; i+=1) { 

strcat(str1, "\x90"); 

} 

下一页我的strcat再次使用:

strcat(str1, "blablabla"); 

,我再次运行循环,此时b次,以连接下一个bx90个字符。最后,我再次使用strcat如下:

strcat(str1, "h\xef\xff\xbf"); 

但是,这两个字符串不匹配。有没有一种更有效的方式来复制C的Python的*的行为?或者我错过了什么?

+4

使用'strcat'在一个循环一样,是二次,正如我最喜欢的一篇博文(由Stack Overflow的创始人之一)中所描述的那样:http://www.joelonsoftware.com/articles/fog0000000319.html除了是一个很好的阅读,它可能会给你一些想法。 –

回答

3
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); 

最后但并非最不重要的,而不是strcat再次strcpy比较好(在这里,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的RETVAL在一些点。

如果memsetmemcpy通话清单越来越长,那么我建议你做这样的:

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' 

甚至创造memsetmemcpy宏:

#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 
0

对于个人1个字节的字符,你可以使用memset部分地复制Python的*的行为:

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

int main(void){ 
    char buffer[100]; 

    memset(buffer,'#',10); 
    buffer[10] = '\0'; 

    printf("%s\n",buffer); 

    memset(buffer, '*', 5); 
    buffer[5] = '\0'; 

    printf("%s\n",buffer); 

    return 0; 
} 

输出:

########## 
***** 

对于更强大的解决方案,请参阅this