例如:
输入(字符串): foo $$ foo ## foo []
搜索(串): foo
输出(数组): $$ ,## ,[]
我尝试过这个:
char * str = "foo $$ foo ## foo []";
char * s = "foo";
int buf_len = 0;
int len = strlen(s);
int i = 0;
char ** buffer = malloc(MAX_BUFFER_SIZE);
char * tmpbuf = malloc(MAX_BUFFER_SIZE);
char * p = str;
char ** buf = buffer;
char * tbuf = tmpbuf;
while(*p)
{
if(*p == *s)
{
while(*p == *(s + i))
{
i++;
p++;
}
if(i == len)
{
*buf ++ = tbuf;
memset(tbuf,0,buf_len);
i = buf_len = 0;
}
}
else
{
*tbuf ++= *p;
buf_len ++;
}
p++;
}
*buf ++= NULL;
int x;
for(x = 0; buffer[x]; x++)
{
printf("%s\n", buffer[x]);
}
free(buffer);
free(tmpbuf);
Run Code Online (Sandbox Code Playgroud)
显示以下输出:
$$ ## []
## []
[]
Run Code Online (Sandbox Code Playgroud)
但预期的是:
$$
##
[]
Run Code Online (Sandbox Code Playgroud)
怎么解决这个问题?
这是一个将字符串拆分为字符串数组的函数:
#include <assert.h>
#include <string.h>
/*
* Split a string by a delimiter.
*
* This function writes the beginning of each item to @pointers_out
* (forming an array of C strings), and writes the actual string bytes
* to @bytes_out. Both buffers are assumed to be big enough for all of the
* strings.
*
* Returns the number of strings written to @pointers_out.
*/
size_t explode(const char *delim, const char *str,
char **pointers_out, char *bytes_out)
{
size_t delim_length = strlen(delim);
char **pointers_out_start = pointers_out;
assert(delim_length > 0);
for (;;) {
/* Find the next occurrence of the item delimiter. */
const char *delim_pos = strstr(str, delim);
/*
* Emit the current output buffer position, since that is where the
* next item will be written.
*/
*pointers_out++ = bytes_out;
if (delim_pos == NULL) {
/*
* No more item delimiters left. Treat the rest of the input
* string as the last item.
*/
strcpy(bytes_out, str);
return pointers_out - pointers_out_start;
} else {
/*
* Item delimiter found. The bytes leading up to it form the next
* string.
*/
while (str < delim_pos)
*bytes_out++ = *str++;
/* Don't forget the NUL terminator. */
*bytes_out++ = '\0';
/* Skip over the delimiter. */
str += delim_length;
}
}
}
Run Code Online (Sandbox Code Playgroud)
用法:
#include <stdio.h>
/* ... */
#define BIG_ENOUGH 1000
int main(void)
{
char *items[BIG_ENOUGH];
char item_bytes[BIG_ENOUGH];
size_t i;
size_t count;
count = explode("foo", "foo $$ foo ## foo []", items, item_bytes);
for (i = 0; i < count; i++)
printf("\"%s\"\n", items[i]);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:
""
" $$ "
" ## "
" []"
Run Code Online (Sandbox Code Playgroud)
这不会产生您要求的确切输出,因为我不确定您希望如何处理"foo"字符串开头处的周围空格和项目分隔符(在您的示例中)的出现.相反,我模仿了PHP的爆炸功能.
我想指出我的explode功能如何在内存管理上发挥作用.由调用者决定缓冲区是否足够大.这对于快速脚本来说很好,但在一个更严肃的程序中可能会很烦人,你需要做一些数学运算才能正确使用这个函数.我本可以编写一个更"强大"的实现来执行自己的分配,但是:
这会使实施变得混乱.
它不会给调用者提供使用自己的内存分配器的选项.
所以实现explode我的方式是"糟糕的",因为它很难正确使用,更糟糕的是,使用方法不正确.另一方面,它是"好"的,因为它分离了功能和内存管理的关注点.