2009-08-04 11 views
3

私は唯一の引数としてchar *をとる関数を持っています。次に、strtok操作を実行します。時にはそれは動作し、時にはそれはdoesentです。それは文字列がどのように構築されたかに依存します。例えば、ここには2つのケースがあります。文字列の割り当ての違いは?

int main() 
{ 
    char glob[] = "/abc/def/ghi"; 
    char *glob2 = "/abc/def/ghi"; 

    func(glob); //this one works 
    func(glob2); //this one doesnt work 

    return 0; 
} 

2つの割り当て方法の違いは何ですか。また、2番目の割り当て方法でstrtokが吹き飛ぶのはなぜですか?

+9

char []とchar *の違いについてlitbの優れた記事を読む - http://stackoverflow.com/questions/308279/c-strings-vs/308724#308724 – Falaina

+3

文字定数をchar *に代入する代わりにconst char *の)は、歴史的な理由からのみ正当です。これは廃止予定と見なされ、一部のコンパイラが警告を出すでしょう。 –

答えて

12

strtok()は、基本的に入力文字列を変更します。 glob2点以上の場合に

char *glob2 = "/abc/def/ghi"; 

データを読み取り専用、したがってそれが失敗し、「char glob[] = "/abc/def/ghi";」は、データが読み取り専用ではないで、一方、それはchar配列で利用できます。したがって、それは変更を可能にする。

+0

マニュアルページからの引用: これらの機能を使用する場合は注意してください。それらを使用する場合は、次の点に注意してください。 - これらの関数は、最初の引数を変更します。 - これらの関数は定数文字列では使用できません。 - 区切り文字のIDは失われます。 - strtok()関数は解析中に静的バッファを使用するため、スレッドセーフではありません。これが問題になる場合は、strtok_r()を使用してください。 –

6

文字列に割り当てられたメモリにStrtokが書き込みを行います。

ほとんどのコンパイラ/ランタイム/ハードウェアで静的に割り当てられた文字列メモリに書き込むことはできません。スタックに書き込むことができます。

7

char [] str1 = "foo"は、スタックにcharの配列を割り当てます(これは関数内にあるものとします)。その配列は問題なく変更できます。

const char * str = "foo"は通常fooという文字列へのポインタを与えます。これは通常は読み取り専用メモリにあります。

char * str = "foo"は同じことを行いますが、暗黙的にconstを削除します(実際にはポインタが読み取り専用メモリを指している可能性があります)。

-2

他のコメントは正しいです。代わりにstrtok_r()を使うべきです。

+0

-1、strtok_rは実際にこの問題に直接関係していないので、* strtok_rとstrtokの両方が入力バッファを変更します –

+0

ああ、そうです。 –

関連する問題