假设这个输入数据:
char input[] = {
0x01, 0x02, 0x0a, 0x0b, /* A 32bit integer */
'h', 'e', 'l', 'l', 'o', 0x00,
'w', 'o', 'r', 'l', 'd', 0x00,
0x00 /* Necessary to make the end of the payload. */
};
开头的 32 整数给出:
const size_t header_size = sizeof (uint32_t);
解析输入可以通过识别“字符串”的第一个字符并存储指向它的指针来完成,然后在找到的字符串很长 (1+) 处继续前进,然后重新开始,直到到达输入的结尾.
size_t strings_elements = 1; /* Set this to which ever start size you like. */
size_t delta = 1; /* 1 is conservative and slow for larger input,
increase as needed. */
/* Result as array of pointers to "string": */
char ** strings = malloc(strings_elements * sizeof *strings);
{
char * pc = input + header_size;
size_t strings_found = 0;
/* Parse input, if necessary increase result array, and populate its elements: */
while ('\0' != *pc)
{
if (strings_found >= strings_elements)
{
strings_elements += delta;
void * pvtmp = realloc(
strings,
(strings_elements + 1) * sizeof *strings /* Allocate one more to have a
stopper, being set to NULL as a sentinel.*/
);
if (NULL == pvtmp)
{
perror("realloc() failed");
exit(EXIT_FAILURE);
}
strings = pvtmp;
}
strings[strings_found] = pc;
++strings_found;
pc += strlen(pc) + 1;
}
strings[strings_found] = NULL; /* Set a stopper element.
NULL terminate the pointer array. */
}
/* Print result: */
{
char ** ppc = strings;
for(; NULL != *ppc; ++ppc)
{
printf("%zu: '%s'\n", ppc - strings + 1, *ppc)
}
}
/* Clean up: */
free(strings);
如果您需要在拆分时复制,请替换此行
strings[strings_found] = pc;
经过
strings[strings_found] = strdup(pc);
free()
并在使用之后和ing之前添加清理代码strings
:
{
char ** ppc = strings;
for(; NULL != *ppc; ++ppc)
{
free(*ppc);
}
}
上面的代码假定负载后面至少有 1 个'\0'
(NUL
也称为空字符)。
如果不满足后一个条件,您需要定义/围绕任何其他终止序列,或者需要知道来自其他来源的输入的大小。如果你不这样做,你的问题就无法解决。
上面的代码需要以下头文件:
#include <inttypes.h> /* for int32_t */
#include <stdio.h> /* for printf(), perror() */
#include <string.h> /* for strlen() */
#include <stdlib.h> /* for realloc(), free(), exit() */
以及它可能需要以下定义之一:
#define _POSIX_C_SOURCE 200809L
#define _GNU_SOURCE
或者您的 C 编译器还需要strdup()
提供什么。