2010-12-28 10 views
7

私はstrtok()をcsv文字列を解析するために使用しています。最初にトークンをトークン化して、そこにいくつのトークンがあるかを調べるので、正しいサイズの文字列を割り当てることができます。前回トークン化に使用したのと同じ変数を使用します。私がそれをもう一度行うたびに、strtok(NULL, ",")は、さらに多くのトークンが解析されていても、NULLを返します。誰かが私が間違っていることを教えてもらえますか?strtok()でcで2回文字列をトークン化

char* tok; 
int count = 0; 
tok = strtok(buffer, ","); 
while(tok != NULL) { 
    count++; 
    tok = strtok(NULL, ","); 
} 

//allocate array 

tok = strtok(buffer, ","); 
while(tok != NULL) { 
    //do other stuff 
    tok = strtok(NULL, ","); 
} 

したがって、2番目のwhileループでは、トークンがさらにあるにもかかわらず最初のトークンが見つかった後に常に終了します。誰かが私が間違っていることを知っていますか?

+2

最近誰もが 'strtok()'が何であるか知っていますが、誰もその文書を読んでいないのですか?誰も私がCを学んでいたときにそれについて話したことはありませんでしたが、私がそれを知るとすぐに、私はそれを読んでいました。 –

答えて

16

strtok()は、操作対象の文字列を変更し、区切り文字をnullに置き換えます。したがって、複数回使用する場合は、コピーを作成する必要があります。

+4

+1:だから、 'strtok()'を使うのは、結局そのような良い考えではないことがよくあります。 –

+0

あなたは勝ちます。 +1は高速回答です。 – Septagram

2

コピーを作成する必要はありません。strtok()は、トークン化する文字列を変更しますが、ほとんどの場合、トークンをもう一度処理する場合は、文字列が既にトークン化されていることを意味します。

はここにあなたのプログラムは、あなたの最初のパスの後にトークンを処理するために少し変更されます:これは私が最初に掲載さよりも、残念ながらトリッキーであることを

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

int main() 
{ 
    int i; 
    char buffer[] = "some, string with , tokens"; 

    char* tok; 
    int count = 0; 
    tok = strtok(buffer, ","); 
    while(tok != NULL) { 
     count++; 
     tok = strtok(NULL, ","); 
    } 


    // walk through the tokenized buffer again 
    tok = buffer; 

    for (i = 0; i < count; ++i) { 
     printf("token %d: \"%s\"\n", i+1, tok); 
     tok += strlen(tok) + 1; // get the next token by skipping past the '\0' 
     tok += strspn(tok, ","); // then skipping any starting delimiters 
    } 

    return 0; 
    } 

注 - strspn()への呼び出しは、「\スキップした後に実行する必要がありますstrtok()によって配置された0を、strtok()は、それが戻すトークンの先頭の区切り文字をスキップします(ソースの区切り文字を置き換えずに)。

+0

もう1つの方法は、最初のパスからのトークンポインタを配列に格納することです。もちろん、それは最大数のトークンまたは動的配列を持つことを意味します。しかし、それはうまくいくかもしれません。 –

1

strsepを使用してください。実際にはポインタが更新されます。あなたの場合は、あなたの文字列のアドレスを渡す代わりにNULLを呼び出す必要があります。 strsepの唯一の問題は、以前にヒープに割り当てられていて、先頭へのポインタを保持してから後で解放する場合です。

char * strsep(char ** string、char * delim);

char * string; char * token; トークン= strsep(&文字列、 "、");

strtokは、Cコースの通常のイントロで使用されます。strsepを使用すると、はるかに優れています。 :-) 「ああ、混乱しないよ - 私はまだ私のポジショニングを台無しにしてしまった。

関連する問題