使用 '\0' 分割字符串
splitting a string using '\0'
假设我有一个 char* ./a.out[=11=]a[=11=]b[=11=][=11=]
。
我想拆分它,结果是一个 char** of value
{
"./a.out[=10=]",
"a[=10=]",
"b[=10=]",
"[=10=]"
}
我使用的是纯 c + POSIX,但如果答案包含 c++STL 的一部分,我不介意,只要避免像 std::string[= 这样的内存效率低下的答案12=]
假设您知道有多少个字符串是相邻的,这是从复合字符串填充指针数组的简单方法:
#include <stdio.h>
#include <string.h>
int main() {
const char *str = "./a.out[=10=]a[=10=]b[=10=]"; // 3 strings
const char *args[3];
const char *p = str;
for (int i = 0; i < 3; i++) {
args[i] = p;
p += strlen(p) + 1;
}
for (int i = 0; i < 3; i++) {
printf("args[%d] = \"%s\"\n", i, args[i]);
}
return 0;
}
输出:
args[0] = "./a.out"
args[1] = "a"
args[2] = "b"
这里有一个封装成函数的替代方案,分配一个数组,扫描字节数组判断字符串的个数,依靠2个连续的空字节来表示链表结束:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
const char **split(const char *str) {
const char **array;
const char *p;
int count = 0, i;
// count the number of strings
for (p = str; *p; p += strlen(p) + 1) {
count++;
}
// allocate the array with an extra element for a NULL terminator
array = calloc(sizeof(*array), count + 1);
if (array != NULL) {
// populate the array with pointers into the string
for (i = 0, p = str; i < count; i++, p += strlen(p) + 1) {
array[i] = p;
}
// set the NULL terminator
array[i] = NULL;
}
return array;
}
int main() {
const char *str = "./a.out[=12=]a[=12=]b[=12=]"; // 4 strings
const char **args = split(str);
for (int i = 0; args[i] != NULL; i++) {
printf("args[%d] = \"%s\"\n", i, args[i]);
}
return 0;
}
输出:
args[0] = "./a.out"
args[1] = "a"
args[2] = "b"
假设我有一个 char* ./a.out[=11=]a[=11=]b[=11=][=11=]
。
我想拆分它,结果是一个 char** of value
{
"./a.out[=10=]",
"a[=10=]",
"b[=10=]",
"[=10=]"
}
我使用的是纯 c + POSIX,但如果答案包含 c++STL 的一部分,我不介意,只要避免像 std::string[= 这样的内存效率低下的答案12=]
假设您知道有多少个字符串是相邻的,这是从复合字符串填充指针数组的简单方法:
#include <stdio.h>
#include <string.h>
int main() {
const char *str = "./a.out[=10=]a[=10=]b[=10=]"; // 3 strings
const char *args[3];
const char *p = str;
for (int i = 0; i < 3; i++) {
args[i] = p;
p += strlen(p) + 1;
}
for (int i = 0; i < 3; i++) {
printf("args[%d] = \"%s\"\n", i, args[i]);
}
return 0;
}
输出:
args[0] = "./a.out"
args[1] = "a"
args[2] = "b"
这里有一个封装成函数的替代方案,分配一个数组,扫描字节数组判断字符串的个数,依靠2个连续的空字节来表示链表结束:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
const char **split(const char *str) {
const char **array;
const char *p;
int count = 0, i;
// count the number of strings
for (p = str; *p; p += strlen(p) + 1) {
count++;
}
// allocate the array with an extra element for a NULL terminator
array = calloc(sizeof(*array), count + 1);
if (array != NULL) {
// populate the array with pointers into the string
for (i = 0, p = str; i < count; i++, p += strlen(p) + 1) {
array[i] = p;
}
// set the NULL terminator
array[i] = NULL;
}
return array;
}
int main() {
const char *str = "./a.out[=12=]a[=12=]b[=12=]"; // 4 strings
const char **args = split(str);
for (int i = 0; args[i] != NULL; i++) {
printf("args[%d] = \"%s\"\n", i, args[i]);
}
return 0;
}
输出:
args[0] = "./a.out"
args[1] = "a"
args[2] = "b"