4

charポインタを使用して配列をトークン化するプログラムを作成しました。プログラムは、区切り文字としてスペースを使用するだけで済みました。提出して完全なクレジットを取得しましたが、提出した後、このプログラムは区切り文字がスペースである場合にのみ機能することに気付きました。

私の質問は、このプログラムを任意の区切り文字で動作させるにはどうすればよいですか?

以下に示す関数は、char配列内の次の単語へのポインターを返します。これは、区切り文字で機能するように変更する必要があると私が信じているものです。

ありがとう!

コード:

char* StringTokenizer::Next(void) {
    pNextWord = pStart;

    if (*pStart == '\0') { return NULL; }

    while (*pStart != delim) {
        pStart++;
    }

    if (*pStart == '\0') { return NULL; }

    *pStart = '\0';
    pStart++;

    return pNextWord;
}

の印刷ループmain()

while ((nextWord = tk.Next()) != NULL) {
    cout << nextWord << endl;
}
4

5 に答える 5

1

最も簡単な方法は、

while (*pStart != delim)

のようなものに

while (*pStart != ' ' && *pStart != '\n' && *pStart != '\t')

または、delimを文字列にして、charが文字列に含まれているかどうかをチェックする関数を作成することもできます。

bool isDelim(char c, const char *delim) {
   while (*delim) {
      if (*delim == c)
         return true;
      delim++;
   }
   return false;
}

while ( !isDelim(*pStart, " \n\t") ) 

または、おそらく最善の解決策は、strtokなど、これらすべてを実行するためのビルド済み関数の1つを使用することです。

于 2010-02-08T05:17:53.717 に答える
1

行を変更するだけ

while (*pStart != delim)

次のように:

while (*pStart != '\0' && strchr(" \t\n", *pStart) == NULL)

標準strchr関数(string.hヘッダーで宣言)は、C文字列(最初の引数で指定)で文字(2番目の引数で指定)を検索し、その文字が最初に出現する位置へのポインターを返します。したがって、 現在の文字( )が文字列内に見つからないため、区切り文字ではないstrchr(" \t\n", *pStart) == NULL場合、式はtrueになります。(もちろん、必要に応じて区切り文字列を変更してください。)*pStart" \t\n"

このアプローチは、特定の文字が対象の(小さな)文字のセットに属しているかどうかをテストするための短くて簡単な方法を提供します。そして、それは標準機能を使用します。

ちなみに、これはC文字列だけでなく、を使用して行うこともできますstd::string。必要なのは、const std::string withのような値を宣言してから、 関数" \t\n"の呼び出しを宣言された区切り文字列のメソッドに置き換えることです。strchrfind

于 2010-02-08T11:16:51.520 に答える
0

うーん...これは完全に正しく見えません:

if (*pStart = '\0')

条件が真になることはありません。==代わりにあなたが意図したと=思いますか?ここでも少し問題があります:

while (*pStart != delim)

文字列の最後の単語の後に区切り文字がない場合、これは文字列の末尾からはみ出し、重大な問題を引き起こします。

編集:本当に自分でこれを行う必要がない限り、ジョブに文字列ストリームを使用することを検討してください。それはすでにすべての正しいメカニズムを備えており、かなり徹底的にテストされています。オーバーヘッドが追加されますが、多くの場合、かなり受け入れられます。

于 2010-02-08T05:18:42.093 に答える
0

コンパイルされていません。しかし、私はこのようなことをします。

 //const int N = someGoodValue;
char delimList[N] = {' ',',','.',';', '|', '!', '$', '\n'};//all delims here.

char* StringTokenizer::Next(void)
{
    if (*pStart == '\0') { return NULL; }

    pNextWord = pStart;

    while (1){  
        for (int x = 0; x < N; x++){
            if (*pStart == delimList[x]){ //this is it.
                *pStart = '\0';
                pStart++;
                return pNextWord;
            }

        }
        if ('\0' == *pStart){ //last word.. maybe.
                return pNextWord;   
        }
        pStart++;
    }
}

// (!compiled).
于 2010-02-08T08:42:02.037 に答える
0

C++ではなくCに固執したいと思います。関数strspnstrcspnは、区切り文字のセットによるトークン化に適しています。strspnを使用して、次のセパレーターが開始する場所(つまり、現在のトークンが終了する場所)を見つけ、次にstrcspnを使用して、セパレーターが終了する場所(つまり、次のトークンが始まる場所)を見つけることができます。最後までループします。

于 2010-02-08T11:41:37.410 に答える