strtok 関数の使用法: 1. 文字列 s に作用し、デリミタとして delim 内の文字を使用して s を部分文字列に分割します; 2. s が NULL の場合、関数 [SAVE_PTR] によって保存されたポインタは、次の呼び出しの開始位置として使用されます。
関連する無料のおすすめ: プログラミング ビデオ コース
strtok 関数の使用方法:
1. 関数の概要
関数プロトタイプ: char *strtok(char *s, char *delim) 関数: 文字列 s に作用し、デリミタとして delim 内の文字を使用して s を部分文字列に分割します。s が NULL の場合、関数によって保存されたポインタ SAVE_PTR は次のように使用されます。通話の開始位置として。 戻り値: 区切り文字に一致した最初の部分文字列2. 主な内容
文字列を分解します。いわゆる分解とは、次のことを意味します。新しい文字列が生成されますが、s が指すコンテンツ内で最初に区切り文字が出現する位置で区切り文字が「/0」に変更されるため、最初の部分文字列 を返すために初めて strtok() が使用されます。 ## 2.
最初の部分文字列の抽出が完了した後、ソース文字列 s の抽出を続けます (2 回目、3 回目、...n 回目の呼び出し)。 strtok の最初のパラメータをヌル値 NULL に割り当てます (
) 3.
このポインタが "\0" を指す場合、つまり、分割された部分文字列はありません。4.
は delim として理解できます 集合 ## 内の文字# と delim は区切り文字として使用できます。
5.strtok が呼び出されたとき、開始位置が区切り文字の場合、開始位置は無視されます。 開始区切り文字
3.
strtok を使用する際の注意点は以下のとおりです。ポイント:
1. この関数の機能は文字列を分解することです。いわゆる分解とは、新しい文字列は生成されず、 s が指す内容に対して何らかの操作が行われるだけであることを意味します。 。したがって、ソース文字列 s が変更されました。 ソース文字列 s が charbuffer[INFO_MAX_SZ]=",Fred 男性 25,John 男性 62,Anna 女性 16" であるとします。フィルター文字列 delim は char *delim = " "、つまりスペースです。は区切り文字です。
バッファーが変更されました。このときバッファ値を出力すると「,Fred」が表示され、その後の「男性 25...16」が消えます。実際、strtok 関数は、delim の区切り文字に基づいて最初に出現する位置、つまり Fred (buffer[5]) の後のスペースを見つけて、それを '/0' に変更します。残りのポジションは変更されません。これは、出力されるバッファーの値がバッファーの内容全体ではなく「,Fred」としてのみ表示される理由を説明しています。
したがって、strtok を使用するときは、ソース文字列が変更されないように注意してください。バッファ内の変更を理解すると、関数の戻り値を説明するのは簡単になります。戻り値 buf は、区切り文字の前の部分文字列です (実際、このステートメントは正確ではありません。「3」の戻り値の詳細な説明を参照してください)。 変数のアドレスから、buf は依然としてソース文字列を指していることに注意してください。
#区切り文字 delim は変更されていないため、これ以上スクリーンショットは取得されません。
2. 部分文字列の最初の抽出後にソース文字列 s の抽出を続行する場合は、次の行を追加する必要があります (2 番目、3 番目、...、n 番目) ) 呼び出しは、strtok の最初のパラメーターをヌル値 NULL に割り当てます。
最初の呼び出しの結果は上記の通り、「,Fred」が抽出されます。また、スペースを境界として次の「男性」などを抽出していきたいと考えています。上の図からわかるように、最初の呼び出し後の最初の呼び出しでは、null 値 NULL を strtok の最初のパラメーターに渡しました ( は、関数が暗黙的に保存された位置から文字列の分解を続けることを意味します)。上記の 2 番目の呼び出しでは、最初の呼び出しが終了する前に、this ポインターを使用して区切り文字の次のビット、つまり 'm' の位置 ) を指すため、
## は#, の順に抽出できます。 。 。 。等々。 。 。 。 。
なぜ null 値を割り当てる必要があるかについては、結論を覚えているか、strtok のソース コードを確認してください。この記事の最後にいくつかの紹介があります。 もちろん、トラブルに巻き込まれるのが好きな人もいます。彼らはルーチンに従ってカードをプレイし、値を代入せずにバッファに代入し続けた場合にどのような結果が生じるかを確認する必要があります。ヌル値。実際、その答えは想像できます。バッファを再度渡すことは、文字列の先頭から区切り文字 delim を検索することと同じであり、この時点でバッファは変更されています (可視部分には ",Fred" だけが残っています)。デリミタ delim が見つかりません。 3. 関数の戻り値に関する考察「1」で述べたように、部分文字列を抽出した場合の strtok の戻り値(戻り値はポインタに割り当てられます。 buf) は、抽出された部分文字列へのポインタです。このポインタは、ソース文字列内の部分文字列の開始位置を指します。部分文字列の末尾の次の文字は、抽出前は区切り文字ですが、抽出後は「/0」に変更されます。 したがって、buf の値を出力すれば、部分文字列の内容は正常に出力できます。
部分文字列が抽出されなかった場合、関数はどのような値を返しますか?
#上の図からわかるように、バッファには区切り文字 delim が含まれていません。 strtok を呼び出した後、buf の値は## です。見つからないため、ソース文字列バッファは変更されていません。buf はソース文字列の最初のアドレスを指し、出力される出力値は文字全体、つまり文字列の完全な値です。
関数の戻り値が NULL になるのはどのような場合ですか?Baidu百科事典には「
分割文字列がない場合はNULLを返す。」と書かれており、非常に曖昧です。この問題を明確に理解したい場合は、strtok の実装原理を確認する必要があるかもしれません。まず実験的な説明をします。
初めて strtok が呼び出されたとき、buf が ",Fred" を指していることは間違いありません。
2 回目の strtok の呼び出しでは、最初のパラメーターが NULL であるため、関数は最後の呼び出しで保存されたこのポインターの位置から分解を続ける、つまり「男性 25」を分解することを意味します。分解が完了すると、buf は「male」を指します。
3 回目の strtok 呼び出しでは、パラメータは NULL に設定され続けますが、このとき、2 回目に保存されたこのポインタの位置、つまり「25」が分解され始めます。区切り文字 delim を含む部分文字列が見つからないため、buf は「25」を指します。
4 回目の呼び出しでは、パラメーターはまだ NULL です。この時点では、3 回目の呼び出しで保存された this ポインターは文字列 '/0' の終わりを指しています。そしてそれ以上進むことはできません。したがって、この関数は NULL を返します。これは百度百科事典に「分割された文字列がない場合、関数は NULL を返します。」と記載されています。 4 .パラメータ区切り文字 delim についての議論 (delim は区切り文字のセットです)
多くの人が strtok を使用するとき、文字列を分割するときに関数が delim= などの区切り文字 delim に完全に一致することを当然のことと考えています。 ab "の場合、文字列「acdab」に対して、関数は「acd」を抽出します。少なくとも私が初めて使ったときはそう思いました。実際、私たちは皆間違っていました。関数のソース コードを見て初めてこの問題に気づきました。次の例を見てみましょう。
ソース文字列はbuffer、区切り文字delimはカンマとスペースです。一般的な考え方によれば、関数を呼び出した後のbufの値は次のようになります。 「フレッド、男性、25歳」、これが結果ですか?
#最初の呼び出し後の結果は、私たちが考えていた結果ではなく、「Fred」であることが判明しました。 ###どうしてこれなの?
GNU C ライブラリの strtok の関数定義に戻ります。「S を DELIM の文字で区切られたトークンに解析する」。つまり、delim に含まれる文字は、厳密な一致の代わりに区切り文字として使用できます。 delim は、区切り文字のコレクションとして理解できます。この点は非常に重要です~
もちろん、文字列を分解するときに複数の区切り文字を使用することはほとんどありません。このため、例を書くときに多くの人が 1 つの区切り文字の場合だけを議論することになります。例を見ると、delim の役割を誤解する人が増えています。
5. 分解される文字列の最初の文字は区切り文字です 最初の文字が区切り文字であることは特別なケースではありません。従来の分解の考え方に従って、文字列を正しく分解することもできます。 私が説明したいのは、strtok はこの状況に対して通常よりも高速な処理方法を採用しているということです。 上の例に示すように。カンマ区切りの文字列「Fred Male 25」は 1 回の呼び出しで取得でき、F の前の「,」は無視されます。strtok は呼び出し時に開始位置から始まる区切り文字を無視することがわかります。 これはstrtokのソースコードから確認できます。
6. 最初のパラメータに文字列定数を渡すことはできません。 この記事で示した例はすべて、ソース文字列を文字列配列変数として保存します。ソース文字列を文字列定数として定義した場合、strtok 関数がソース文字列の値を変更しようとするため、プログラムが例外をスローすることが想像できます。以上がstrtok関数の使い方は何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。