メニュー
検索
言語
タグ
文字列を区切り文字で分割しポインタ配列を返す関数 (split)
総合評価: - 作成日: 2025-10-05
コメント:
Linuxでメモリリークテスト済み。
Windows/Linuxで動作確認済み。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
void
split_free_array(char **array) {
for (char **p = array; *p; p++) {
free(*p);
}
free(array);
}
static void
split_show_array(char **array) {
for (char **p = array; *p; p++) {
printf("[%s]\n", *p);
}
}
size_t
split_count(char **array) {
size_t n = 0;
for (char **p = array; *p; p++) {
n++;
}
return n;
}
/**
* 文字列strをsepで分割する。
* 返り値は動的確保された文字列のポインタ配列。
*/
char **
split(char sep, const char *str) {
#undef buf_alloc
#define buf_alloc() {\
free(buf);\
buf = malloc(buf_capa + 1);\
if (!buf) {\
goto fail;\
}\
buf[0] = 0;\
buf_len = 0;\
}\
#undef buf_resize
#define buf_resize() {\
if (buf_len >= buf_capa) {\
buf_capa *= 2;\
char *tmp = realloc(buf, buf_capa + 1);\
if (!tmp) {\
goto fail;\
}\
buf = tmp;\
}\
}\
#undef array_resize
#define array_resize() {\
if (array_len >= array_capa) {\
array_capa *= 2;\
byte = sizeof(char*);\
size = byte * array_capa + byte;\
char **tmp = realloc(array, size);\
if (!tmp) {\
goto fail;\
}\
array = tmp;\
}\
}\
#undef push_array
#define push_array() {\
array_resize();\
array[array_len++] = buf;\
array[array_len] = NULL;\
buf = NULL;\
buf_alloc();\
}\
#undef push_buf
#define push_buf(c) {\
buf_resize();\
buf[buf_len++] = c;\
buf[buf_len] = 0;\
}\
if (!str) {
return NULL;
}
size_t buf_capa = 4;
size_t buf_len = 0;
char *buf = NULL;
buf_alloc();
size_t array_capa = 4;
size_t array_len = 0;
size_t byte = sizeof(char*);
size_t size = byte * array_capa + byte;
char **array = malloc(size);
if (!array) {
goto fail;\
}
array[array_len] = NULL;
for (const char *p = str; *p; p++) {
if (*p == sep) {
push_array();
} else {
push_buf(*p);
}
}
push_array();
free(buf);
return array;
fail:
free(buf);
split_free_array(array);
return NULL;
}
int
main(void) {
char **toks;
assert(split(',', NULL) == NULL);
toks = split(',', "");
assert(toks);
assert(split_count(toks) == 1);
split_show_array(toks);
assert(!strcmp(toks[0], ""));
split_free_array(toks);
toks = split(',', "123,223,,323");
assert(toks);
split_show_array(toks);
assert(split_count(toks) == 4);
assert(!strcmp(toks[0], "123"));
assert(!strcmp(toks[1], "223"));
assert(!strcmp(toks[2], ""));
assert(!strcmp(toks[3], "323"));
split_free_array(toks);
toks = split(',', ",,,");
assert(toks);
split_show_array(toks);
assert(split_count(toks) == 4);
assert(!strcmp(toks[0], ""));
assert(!strcmp(toks[1], ""));
assert(!strcmp(toks[2], ""));
assert(!strcmp(toks[3], ""));
split_free_array(toks);
return 0;
}