次のようなデータを含む CSV ファイルがあります。
value;name;test;etc
を使用して分割しようとしていstrtok(string, ";")
ます。ただし、このファイルには、次のような長さ 0 のデータを含めることができます。
value;;test;etc
strtok()
スキップします。strtok
このような長さゼロのデータをスキップしないようにする方法はありますか?
strsep()
可能であれば、 の代わりにBSD 関数を使用することstrtok()
もできます。マニュアルページから:
この
strsep()
関数は、関数の代替として意図されていstrtok()
ます。このstrtok()
関数は移植性の理由から優先されるべきですが (ISO/IEC 9899:1990 ("ISO C90") に準拠しています)、空のフィールドを処理することはできません。つまり、2 つの隣接する区切り文字で区切られたフィールドを検出したり、一度に複数の文字列。このstrsep()
関数は、4.4BSD で初めて登場しました。
簡単な例 (これも man ページからコピー):
char *token, *string, *tofree;
tofree = string = strdup("value;;test;etc");
while ((token = strsep(&string, ";")) != NULL)
printf("token=%s\n", token);
free(tofree);
出力:
トークン=値 トークン= トークン=テスト トークン=など
そのため、空のフィールドは正しく処理されます。
もちろん、他の人が言ったように、これらの単純なトークナイザー関数は引用符内の区切り文字を正しく処理しないため、それが問題になる場合は、適切なCSV 解析ライブラリを使用する必要があります。
このように動作しないようにする方法はありませstrtok()
ん。マンページから:
解析された文字列内の連続する 2 つ以上の区切り文字バイトのシーケンスは、単一の区切り文字と見なされます。文字列の先頭または末尾の区切り文字バイトは無視されます。別の言い方をすれば、 strtok() によって返されるトークンは常に空でない文字列です。
ただし、検出されたすべてのトークンを に置き換えるため、できること'\0'
は、トークンの前の文字数を確認することです。そうすれば、スキップされたトークンの数がわかります。ソース情報:strtok()
'\0'
このトークンの末尾は自動的にヌル文字に置き換えられ、トークンの先頭が関数によって返されます。
そして、私が何を意味するかを示すコードサンプル。
char* aStr = ...;
char* ptr = NULL;
ptr = strtok (...);
char* back = ptr;
int count = -1;
do {
back--;
if (back <= aStr) break; // to protect against reads before aStr
count++;
} while (*back = '\0');
(ide またはテストなしで記述されたものは、無効な実装である可能性がありますが、アイデアは有効です)。
いいえ、できません。「男strtok」より:
解析された文字列内の 2 つ以上の連続する区切り文字のシーケンスは、単一の区切り文字と見なされます。文字列の先頭または末尾の区切り文字は無視されます。別の言い方をすれば、 strtok() によって返されるトークンは常に空でない文字列です。
データに引用符内の区切り文字またはその他の「エスケープ」が含まれている場合にも、問題が発生する可能性があります。
最善の解決策は、CSV 解析ライブラリを入手するか、独自の解析関数を作成することだと思います。