C言語のstrtok_r関数とは?strtokとの違いと使い方を解説
C言語のstrtok_r()関数は、文字列を区切り文字で分割するための標準ライブラリ関数です。従来のstrtok()関数とよく似た機能を持っていますが、両者には決定的な違いがあります。それが関数名に付いている「_r」の部分で、これは「リエントラント(re-entrant:再入可能)」であることを意味しています。
リエントラント関数とは何か
リエントラント関数とは、実行中に割り込みが発生しても安全に処理を中断でき、後から中断した箇所から実行を再開できる関数のことです。この特性により、リエントラント関数は「スレッドセーフ」であると言われます。つまり、複数のスレッドから同時に呼び出されても、互いに干渉することなく安全に動作するのです。
通常のstrtok()関数は内部に静的な状態を持つため、マルチスレッド環境では予期しない動作を引き起こす恐れがあります。一方、strtok_r()関数には「context(コンテキスト)」と呼ばれる追加の引数があり、分割の進行状況を呼び出し元側で管理できます。この仕組みのおかげで、関数は常に正しい位置から処理を再開できるようになっています。
strtok_r()関数の構文
strtok_r()関数の構文は以下の通りです。
#include <string.h> char *strtok_r(char *string, const char *limiter, char **context);
- string:分割対象の文字列(2回目以降の呼び出しではNULLを指定)
- limiter:区切り文字の集合
- context:分割状態を保持するためのポインタへのポインタ
サンプルプログラム
以下は、strtok_r()関数を使って文字列をスペースで分割するC言語プログラムの例です。
#include <stdio.h>
#include <string.h>
int main(){
char input_string[] = "Hello Tutorials Point";
char token_list[20][20];
char* context = NULL;
char* token = strtok_r(input_string, " ", &context);
int num_tokens = 0; // トークンリストのインデックス
while (token != NULL){
strcpy(token_list[num_tokens], token); // リストへコピー
num_tokens++;
token = strtok_r(NULL, " ", &context);
}
// トークンのリストを表示
printf("Token List:\n");
for (int i=0; i < num_tokens; i++) {
printf("%s\n", token_list[i]);
}
return 0;
}
実行結果
上記のプログラムを実行すると、次のような出力が得られます。
Token List: Hello Tutorials Point
まとめ
strtok_r()関数は、strtok()関数のスレッドセーフ版とも言える関数です。context引数によって分割状態を管理することで、マルチスレッド環境でも安全に文字列分割を行える点が最大の特徴です。なお、strtok_r()はPOSIX規格で定義されているため、LinuxなどのUNIX系環境で利用できます。Windows環境では、同様の目的でstrtok_s()関数が用意されていますので、用途に応じて使い分けるとよいでしょう。
-
C言語のstrcmp()関数とは?文字列比較の基本と使い方を徹底解説
C言語の標準ライブラリ関数 int strcmp(const char *str1, const char *str2) は、ポインタ str1 が指し示す文字列と、str2 が指し示す文字列を比較するための関数です。C言語において、文字型の配列は「文字列」と呼ばれます。まずは文字列の基本的な扱い方から確認していきましょう。文字列の宣言文字列(文字配列)の宣言は以下のように行います。char stringname [size];例えば、char string[50]; と宣言すれば、最大50文字の長さを持つ文字列を格納できます。文字列の初期化文字列の初期化には、主に次の2つの方法があります。1
-
C言語のstrcpy()関数とは?基本構文と使い方をわかりやすく解説
C言語のライブラリ関数 char *strcpy(char *dest, const char *src) は、src が指し示す文字列を dest にコピーするための関数です。 C言語では、文字の配列のことを「文字列」と呼びます。 文字列の宣言 文字列(文字配列)の宣言は、以下の形式で行います。 char stringname[size]; 例えば char string[50]; と宣言すると、最大50文字の文字列を格納できる配列が確保されます。 文字列の初期化 文字列の初期化には、主に以下の2つの方法があります。 1. 文字定数を使う方法 char string[10] = {H,