C LANGUAGE TECHNOLOGY

【C言語】strtok/strtok_r/strsep関数の注意点と使い方【自作関数も紹介】

悩んでいる人

C言語で文字列の分割方法を教えて!

こういった悩みにお答えします.

本記事の信頼性

  • リアルタイムシステムの研究歴12年.
  • 東大教員の時に,英語でOSの授業.
  • 2012年9月~2013年8月にアメリカのノースカロライナ大学チャペルヒル校コンピュータサイエンス学部2021年の世界大学学術ランキングで20位)で客員研究員として勤務.C言語でリアルタイムLinuxの研究開発
  • プログラミング歴15年以上,習得している言語: C/C++Solidity,Java,Python,Ruby,HTML/CSS/JS/PHP,MATLAB,Assembler (x64,ARM).
  • 東大教員の時に,C++言語で開発した「LLVMコンパイラの拡張」,C言語で開発した独自のリアルタイムOS「Mcube Kernel」GitHubにオープンソースとして公開

こういった私から学べます.

strtok/strtok_r/strsep関数

strtok/strtok_r/strsep関数と注意点を解説していきます.

strtok関数

strtok関数は,第1引数strの文字列を0個以上の空でないトークンに分割します.

第2引数のdelimには,解析対象の文字列をトークンに分割するために利用する文字列(分割文字の集合)を指定します.

strtok関数の最初の呼び出しでは,解析する文字列をstrで指定します.

同じ文字列を解析する2回目以降の呼び出しでは,strはNULLでなければなりません.

strtok_r関数

strtok_r関数は,strtok関数のリエントラント版です.

第3引数のsaveptrは,同じ文字列を解析する連続した呼び出しの間でコンテキストを維持するためにstrtok_r関数の内部で利用するchar *型の変数へのポインタです.

strtok_r関数の最初の呼び出しでは,解析する文字列をstrで指定し,saveptrの値は無視されます.

※実装によっては,strtok_r関数を最初に呼び出してstrを解析する際,saveptrをNULLに設定する必要があります.

同じ文字列を解析する2回目以降の呼び出しでは,strはNULLでなければならず,saveptr(およびそれが指すバッファ)は前回の呼び出しから変更されていなければなりません.

strtok_r関数はGCC/Clangでは実行できますが,C89/C99準拠ではないのでVisual Studioでは実行できないことに注意して下さい.

strsep関数

strsep関数は,strtok/strtok_r関数と同様に文字列をトークンに分割して取り出します.

strtok/strtok_r関数とは異なり,strsep関数は空のフィールドを扱うことができます.

strtok_関数と同様に,strsep関数はVisual Studioでは実行できないことに注意して下さい.

移植性を考慮する場合は,C89/C99準拠のstrtok関数の利用をおすすめします.

strtok/strtok_r/strsep関数の注意点

strtok/strtok_r/strsep関数の注意点は以下になります.

知らないとバグの原因になりますので,利用する時は注意しましょう.

  • 最初の引数を変更すること(関数の呼び出し後は違う文字列に変更)
  • 定数文字列には使えないこと(例:const型修飾子で宣言されている文字列,char *s型で定義された文字列)
  • 区切り文字自体は失われてしまうこと('\0'文字で上書き)

strtok/strtok_r/strsep関数の使い方

strtok/strtok_r/strsep関数の使い方を紹介していきます.

strtok関数の使い方

strtok関数の使い方は以下のコードになります.

実行結果は以下になります.

文字列をトークンに分割できていること,str2の空のフィールド(「abc,,de」の「,,」の間の部分)は読み飛ばしていることがわかります.

strtok_r関数の使い方

strtok_r関数の使い方は以下のコードになります.

実行結果は以下になります.

saveptrを利用して正しく文字列をトークンに分割できていることがわかります.

strsep関数の使い方

strsep関数の使い方は以下のコードになります.

実行結果は以下になります.

strtok/strtok_r関数とは異なり,strsep関数は空のフィールドをtokenとして分割できていることがわかります(9行目の「token =」).

strtok/strtok_r/strsep関数の自作関数

strtok/strtok_r/strsep関数の自作関数を紹介します.

strtok/strtok_r/strsep関数は少し使いづらい点がありますので,自作関数のコードを参考にしてあなただけの文字列をトークンに分割する関数を作成して頂いても構いません.

strtok関数の自作関数

strtok関数の自作関数「mystrtok関数」のコードは以下になります.

実行結果は以下にになります.

strtok関数と同じ動作になっていることがわかります.

strtok_r関数の自作関数

strtok_r関数の自作関数「mystrtok_r関数」のコードは以下になります.

実行結果は以下になります.

strtok_r関数と同じ動作になっていることがわかります.

strsep関数の自作関数

strsep関数の自作関数「mystrsep関数」のコードは以下になります.

mystrsep関数では,strpbrk関数の自作関数「mystrpbrk関数」を呼び出しています.

strpbrk関数は,文字列からバイト集合(文字列)を探して,最初に発見したバイトのポインタを返す関数です.

実行結果は以下になります.

strsep関数と同じ動作になっていることがわかります.

まとめ

C言語のstrtok/strtok_r/strsep関数の注意点と使い方,自作関数を紹介しました.

strtok/strtok_r/strsep関数は結構難しいので,使い方を正しく理解しましょう.

本記事のコードでは,文字列をトークンに分割する区切り文字はカンマ「,」に設定しています.

文字列(データ)をカンマで区切って管理するCSVファイルの読み書き方法を知りたいあなたはこちらからどうぞ.

C言語 CSVファイル
【C言語】CSVファイルの読み書き【C++/Python言語でも紹介】

こういった悩みにお答えします. こういった私から学べます. 目次1 C言語でCSVファイルの読み書き2 参考:C++/Python言語でCSVファイルの読み書き2.1 C++言語でCSVファイルの読み ...

続きを見る

C言語を独学で習得することは難しいです.

私にC言語の無料相談をしたいあなたは,公式LINE「ChishiroのC言語」の友だち追加をお願い致します.

友だち追加

独学が難しいあなたは,C言語を学べるおすすめのオンラインプログラミングスクール5社で自分に合うスクールを見つけましょう.後悔はさせません!

-C LANGUAGE, TECHNOLOGY
-, , , , , , , , ,