strtok とトークン化
文字列を分割します。
「strtok とトークン化」はCoddyKit上の無料C Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはC Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 C Academyコースには全4レッスンが含まれています。
トークン化とは
トークン化とは、区切り文字で分けられた文字列を、より小さな部分(トークン)に分割することです。
たとえば、"a,b,c"をカンマで分割すると、トークンa、b、cが得られます。Cでは、この処理にstrtokを使用できます。
#include <stdio.h>
#include <string.h>
int main(void) {
char text[] = "a,b,c";
char *token = strtok(text, ",");
printf("First token: %s\n", token);
return 0;
}strtokのシグネチャ
char *strtok(char *str, const char *delim);
最初の呼び出しでは文字列を渡します。後続の呼び出しではNULLを渡すと、前回の続きから処理されます。次のトークンを返し、処理が完了するとNULLを返します。
#include <stdio.h>
#include <string.h>
int main(void) {
char text[] = "red green blue";
char *tok = strtok(text, " ");
while (tok != NULL) {
printf("%s\n", tok);
tok = strtok(NULL, " ");
}
return 0;
}strtokは文字列を変更する
重要:strtokは元の文字列を変更します。各区切り文字を'\0'に置き換え、同じバッファー内を指すポインターを返します。
そのため、読み取り専用の文字列リテラルである"a,b"をトークン化することはできません。
#include <stdio.h>
#include <string.h>
int main(void) {
char data[] = "x:y:z";
strtok(data, ":");
printf("data[1] is now: %d (the null byte)\n", data[1]);
return 0;
}書き込み可能なコピーを作る
strtokは入力を破壊するため、後で元の文字列が必要な場合は先にコピーしてください。
ローカルのchar配列を使うか、strcpyでバッファーにコピーしてください。
#include <stdio.h>
#include <string.h>
int main(void) {
const char *original = "one-two-three";
char copy[64];
strcpy(copy, original);
char *tok = strtok(copy, "-");
while (tok) {
printf("%s\n", tok);
tok = strtok(NULL, "-");
}
printf("Original intact: %s\n", original);
return 0;
}複数の区切り文字
delim引数は文字の集合であり、文字の並びではありません。集合内の任意の文字が区切り文字として扱われます。
そのため、" ,;"を指定すると、空白、カンマ、セミコロンのすべてで同時に分割されます。
#include <stdio.h>
#include <string.h>
int main(void) {
char text[] = "a,b;c d";
char *tok = strtok(text, ",; ");
while (tok) {
printf("[%s]\n", tok);
tok = strtok(NULL, ",; ");
}
return 0;
}連続する区切り文字
strtokは、連続する区切り文字を1つの区切りとして扱い、空のトークンをスキップします。
したがって、"a,,b"から得られるのはaとbだけで、間に空のトークンはありません。空のフィールドが重要なCSV解析では、この点に注意してください。
#include <stdio.h>
#include <string.h>
int main(void) {
char text[] = "a,,b";
char *tok = strtok(text, ",");
while (tok) {
printf("token: %s\n", tok);
tok = strtok(NULL, ",");
}
return 0;
}トークン数を数える
よくある処理として、文字列に含まれるトークンの数を数えることがあります。ループ内でカウンターを増やしてください。
#include <stdio.h>
#include <string.h>
int main(void) {
char sentence[] = "the quick brown fox";
int count = 0;
char *tok = strtok(sentence, " ");
while (tok) {
count++;
tok = strtok(NULL, " ");
}
printf("Word count: %d\n", count);
return 0;
}strtokは隠れた状態を保持する
strtokは位置を静的な内部変数に保存します。そのため、NULLを渡すと前の文字列の続きから処理できます。
一方で、これは再入可能ではなく、スレッドセーフでもありません。2つの文字列を同時にトークン化することはできません。
#include <stdio.h>
#include <string.h>
int main(void) {
char a[] = "1 2";
char *t = strtok(a, " ");
printf("%s\n", t);
t = strtok(NULL, " ");
printf("%s\n", t);
return 0;
}トークンの保存
分割後もトークンを使うには、返されたポインターを配列に保存します。これらは変更後のソースバッファー内を指しているため、バッファーは有効な状態を保つ必要があります。
#include <stdio.h>
#include <string.h>
int main(void) {
char csv[] = "name,age,city";
char *fields[10];
int n = 0;
char *tok = strtok(csv, ",");
while (tok && n < 10) {
fields[n++] = tok;
tok = strtok(NULL, ",");
}
for (int i = 0; i < n; i++)
printf("Field %d: %s\n", i, fields[i]);
return 0;
}再入可能な代替手段
POSIXにはstrtok_rがあり、隠れた状態の代わりに明示的なchar **saveptrを受け取ります。これにより、入れ子にしたり複数のスレッドで使ったりしても安全です。
移植性のある標準Cでは、1回の解析処理に限れば通常のstrtokで問題ありません。
#include <stdio.h>
#include <string.h>
int main(void) {
char text[] = "p:q:r";
char *save;
char *tok = strtok_r(text, ":", &save);
while (tok) {
printf("%s\n", tok);
tok = strtok_r(NULL, ":", &save);
}
return 0;
}実践:パスを分割する
トークン化は、ファイルパスのような構造化テキストの解析で特に役立ちます。/で分割すると、各パス要素を取り出せます。
#include <stdio.h>
#include <string.h>
int main(void) {
char path[] = "usr/local/bin";
char *part = strtok(path, "/");
while (part) {
printf("-> %s\n", part);
part = strtok(NULL, "/");
}
return 0;
}クイックチェック
strtokの仕組みについての理解度を確認しましょう。
まとめ
strtokで文字列を分割する方法について学びました。
- 最初の呼び出しでは文字列を渡し、後続の呼び出しではNULLを渡します。
- 入力を変更し、区切り文字を
'\0'に置き換えます。読み取り専用の文字列は先にコピーしてください。 - 区切り文字の引数は集合であり、連続する区切り文字はまとめて扱われます。
- 静的な状態を使用するためスレッドセーフではありません。必要に応じて
strtok_rを使用してください。
よくある質問
「strtok とトークン化」レッスンは無料ですか?
はい。「strtok とトークン化」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、C Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 C Academyコースには全4レッスンが含まれています。
「strtok とトークン化」で何を学びますか?
文字列を分割します。 ブラウザで直接実行するハンズオンコードでC Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
C Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのC Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。
「strtok とトークン化」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このC Academyレッスンでコードを書いて実行できますか?
はい。すべてのC Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- strlen、strcpy、strcat
- strcmp と比較
- strtok とトークン化
- memcpy と memset