しかしこの関数では区切り文字が連続した場合、その部分をまとめて次のデータに飛んでしまいます
この場合、CSVのヌルデータ等は正常に処理できません
ということでそのような連続した区切り文字が存在する場合も次に飛ばないような関数を作ってみました
#include <stdio.h>
#include <string.h>
char *strtoks(char
*s1, const char
*s2) {
static char *str = 0;
register int i, j;
if (s1) {
str = s1;
} else {
s1 = str;
}
if (!s1) { return(0); }
j = strlen(s2);
while (1) {
if
(!*str) {
str = 0;
return(s1);
}
for (i
= 0; i < j; i++) {
if
(*str == s2[i]) {
*str++ = 0;
return(s1);
}
}
str++;
}
}
char *strtokc(char
*s1, char s2) {
static char *str = 0;
if (s1) {
str = s1;
} else {
s1 = str;
}
if (!s1) { return(0); }
while (1) {
if
(!*str) {
str = 0;
return(s1);
}
if
(*str == s2) {
*str++ = 0;
return(s1);
}
str++;
}
}
int main(int
argc, char *argv[]) {
char str1[]
= "10,20,30,,50,60,,,90";
char str2[]
= "10,20,30,,50,60,,,90";
char str3[]
= "10,20,30,,50,60,,,90";
char *p;
printf("strtok\n");
p = strtok(str1, ",");
while (p) {
static int cnt = 0;
printf("%d:\"%s\"\n",
++cnt, p);
p = strtok(0, ",");
}
printf("\nstrtoks\n");
p = strtoks(str2, ",");
while (p) {
static int cnt = 0;
printf("%d:\"%s\"\n",
++cnt, p);
p = strtoks(0, ",");
}
printf("\nstrtokc\n");
p = strtokc(str3, ',');
while (p) {
static int cnt = 0;
printf("%d:\"%s\"\n",
++cnt, p);
p = strtokc(0, ',');
}
return(0);
}
strtoksは複数の区切り文字のいずれかが出てきたらそこで区切ります
strtokcは区切り文字は文字列ではなく文字として渡します そのため若干パフォーマンスが向上します
実行結果は
strtok
1:"10"
2:"20"
3:"30"
4:"50"
5:"60"
6:"90"
strtoks
1:"10"
2:"20"
3:"30"
4:""
5:"50"
6:"60"
7:""
8:""
9:"90"
strtokc
1:"10"
2:"20"
3:"30"
4:""
5:"50"
6:"60"
7:""
8:""
9:"90"
という感じです
strtokではスキップしてしまうところも正常に処理しています
なお、strtoksおよびstrtokcのヌルデータはptr[0] = '\0'となっています
例えば整数型が入っていると仮定し、整数型から変換する関数に渡した場合、場合によっては問題が発生する可能性があります
その可能性が有る場合は最初にヌルデータか否かを確認する必要があります
あと、わざわざ説明する必要もないと思いますが、strtokや上記の関数は受け取ったデータを破壊します
char *str = "123,456,789"; p = strtok(str, ","); とかやらないよーに
strtokではスキップしてしまうところも正常に処理しています
なお、strtoksおよびstrtokcのヌルデータはptr[0] = '\0'となっています
例えば整数型が入っていると仮定し、整数型から変換する関数に渡した場合、場合によっては問題が発生する可能性があります
その可能性が有る場合は最初にヌルデータか否かを確認する必要があります
あと、わざわざ説明する必要もないと思いますが、strtokや上記の関数は受け取ったデータを破壊します
char *str = "123,456,789"; p = strtok(str, ","); とかやらないよーに
すばらしいです。学校で同じ問題があり苦戦しています。ありがとうございました。
返信削除