0

strtok最後のトークンの場所に NULL を挿入することによって入力文字列を変更するという事実のために、注意して考慮する必要があることを常に理解しています。これはcppreferenceによっても検証されます。

ただし、cplusplus.com の例を検証しようとすると、32 ビット Windows 7 の VS2010 で、実際には strtok が元の文字列に NULL を挿入していないことがわかりました。例の引数の NULL を str に変更することでこれを特定できました。プログラムはループを繰り返し、"This" をトークンとして渡します。 cppreferenceが主張するように、ポインター。

また、文字列リテラルの定数性に問題があるのではないかと思ったので、文字列をコピーしました

char str2[] ="- This, a sample string.";
char str[50];
strcpy(str,str2);

もう一度実行しましたが、ループが繰り返されました。デバッガーは、入力文字列が変更されていないことを示しています。

ここで私が間違っている場所を誰かが説明できますか? 編集:「以前に保存されたポインターがstrとして渡された場合と同じ動作です」の私の解釈だと思います。

ありがとうございました。

編集:正確なコード:

/* strtok example */
#include <iostream>
#include <stdio.h>
#include <string.h>

int main ()
{
  char str2[] ="- This, a sample string.";
  char str[50];
  strcpy(str,str2);
  char * pch;
  printf ("Splitting string \"%s\" into tokens:\n",str);
  pch = strtok (str," ,.-");
  while (pch != NULL)
  {
    printf ("%s\n",pch);
    pch = strtok (str, " ,.-");
    printf("%s\n", str);
  }
  std::cin.ignore();
  return 0;
}

コードからの出力:

Splitting string "- This, a sample string." into tokens:
This
- This
This
- This
This
- This
This
- This
This
- This
This
- This
This
- This

編集: 解決済み このガベージを削除するか、そのままにしておく必要がありますか? これに対処しなければならなかった貧しい人々からポイントを奪いたくありません。

4

2 に答える 2

4

引数の NULL を例から str に変更することでこれを特定でき、プログラムは繰り返しループします

これを行うのは、str(または非 NULL ポインター)を渡すと最初strtok()からやり直すため、単一のトークンになったものをトークン化する (何度も返す) ためです。これは、NULL 以外のポインターが に渡された場合の文書化された動作strtok()です。

NULLに最初の引数として渡すと、strtok()前回中断したところから再開するように指示されます (静的変数のどこかでその状態を追跡しますが、これは の問題の 1 つですstrtok())。

于 2012-10-25T19:29:01.397 に答える
3

まず、NULL元の文字列に挿入されるのではなく、ゼロ文字が挿入されます。これはおそらくあなたが言いたかったことだと私は理解していますが、よく知られた完全に無関係なマクロを含めることはまだ良い考えではありませんNULL

次に、strtok元の文字列へのゼロ文字の挿入に失敗した場合、意図したとおりに機能しません。このため、実験結果をどういうわけか誤解していたと思います。strtok32ビットWindows7のVS2010でも入力文字列を変更します。


投稿したコードからの出力は、文字列が変更されたことを明確に示しています。の元の値はstrでした"- This, a sample string."strループの内側から印刷された値はちょうど"- This"です。strtok文字列は、直後にゼロ文字が挿入されたために特に切り捨てられました"- This"(より正確には、,文字が文字に置き換えられまし\0)。

于 2012-10-25T19:23:52.090 に答える