Menü
Bedava
giriş
ana  /  Sorunlar / StrTok S C Açıklama. Adam Strtok_r (3): Dizeden elemanların (belirteçlerin) çıkarılması

Strtok S C Açıklama. Adam Strtok_r (3): Dizeden elemanların (belirteçlerin) çıkarılması

4 cevap

Strtok hakkında bilmeniz gereken iki şey. Bahsedildiği gibi, "iç durumunu destekliyor." Buna ek olarak beslediğiniz dizgiyi şımarttı. Temel olarak, sağladığınız işaretleyiciyi bulacağı ve işaretçiyi çizginin başlangıcına getireceği "\\ 0" yazacaktır. Dahili olarak, son Tokeny'nin yerini destekler; Ve bir sonraki diyorsun, oradan başlayacak.

Önemli bir sonuç, bir çizgi tipi Const Char * "Hello World" için Strtok kullanamayacağınızdır; Const Char * String'in içeriğini değiştirirken erişim ihlali alacağınız için.

Strtok'ta "iyi bir şey", aslında satırları kopyalamamasıdır, bu nedenle ek bellek tahsisini vb. Kontrol etmeniz gerekmez. Ancak yukarıda belirtilenleri anlamadıysanız, kullanımı ile ilgili sorunlarınız olacaktır.

Misal. "Bu, bir dize var" varsa, Seri Aramalar Strtok, aşağıdaki gibi işaretçiler oluşturacaktır (değer ^ iade değeridir). Lütfen belirteçlerin bulunduğu yerdeki "\\ 0" eklendiğini unutmayın; Bu, orijinal dizenin değiştirildiği anlamına gelir:

T, a, string \\ 0 bu, bir, bir, dize bu, a, a, string \\ 0 bu ^ bu \\ 0 \\ 0 a, string \\ 0 ^ bu \\ 0 \\ 0 a \\ 0 string \\ 0 a ^ Bu \\ 0 \\ 0 A \\ 0 string \\ 0 string ^

Umarım mantıklı geliyor.

Strtok () işlevi, çağrılar arasındaki verileri saklar. NULL Pointer'ı kullanarak aradığınızda bu verileri kullanır.

Son belirteç bulunduğu nokta, aşağıdaki çağrının yanında kullanılacak bir fonksiyon kullanıldığı nokta (veri arızalarını önlemek için belirli bir kütüphane gerekir).

strtok, iç durumu destekler. Buna null olarak aradığınızda, teslim ettiğiniz dizeyi kullanmak için kendinizi yeniden başlatır. Buna null ile aradığınızda, bu satırı ve şu anda aşağıdaki belirteçleri iade edecek herhangi bir durumu kullanır.

Strtok'un nasıl çalıştığından dolayı, yazarsanız, çok iş parçacıklı bir C'nin yerine getirilmesiyle bağlantı kurduğunuzdan emin olmalısınız. Çok Dişli Uygulama. Bu, her ipliğin strtok için kendi iç durumlarını almasını sağlar.

Strtok işlevi, verileri tüm iplikler arasında dağıtılan bir dahili statik değişkene kaydeder.

Güvenlik güvenliğini sağlamak için, Strtok_r kullanmanız gerekir.

Statik char * sonuna bakın;

Char * Strtok (S, Sınır) Kayıt CHAR * S; Kayıt Const Char * Delim; (KAYIT CHAR * Spanp; Int C, SC; char * TOK; statik char * son; eğer (s \u003d\u003d null && (s \u003d son) \u003d\u003d null) geri dönüş (null); / * * atla (span) lider Sınırlayıcılar (S + \u003d strSPN (S, DELIM), tür). * / CONTRA: C \u003d * S ++; (spanp \u003d (char *) DELIM; (SC \u003d * Spanp ++)! \u003d 0;) (eğer (c \u003d\u003d sc) devam edin;) eğer (c \u003d\u003d 0) (/ * sınırsız karakter yok * / son \u003d null; geri dönüş (null);) TOK \u003d s - 1; / * * Tarama belirteci (Sınırlayıcılar için tara: S + \u003d strCSPN (S, DELIM), Sıralama. * Delimin bir NUL olması gerektiğini unutmayın; Bunu görürsek, ben de görürsek dururuz. * / İçin (;) (c \u003d * s + +; Spanp \u003d (char *) Delim; Yapın ((((((SC \u003d * Spanp ++) \u003d\u003d c) (eğer (c \u003d\u003d 0) s \u003d null; başka s [-1] \u003d 0; Son \u003d S ; Geri dönüş (tok);)) iken (sc! \u003d 0);) / * not kırılmış * /)

Paylaş

#Dahil etmek. Char * Strtok (Char * str1, Const char * str2.);

Strtok () işlevi, işaretçiyi parametreyi adresleyen dizgedeki bir sonraki LEX'e döndürür. str1. Parametre tarafından adreslenebilir bir dize oluşturan semboller str2.bir lex tanımlayan bölücülerdir. İade edilecek bir Lexeme yokluğunda, sıfır bir işaretçi iade edilir.

C99 sürümünde parametrelere str1 ve str2. Uygulanan niteleyicileri kısıtlayın.

Strtok işlevi ilk önce parametreyi aradığında, bazı dizeleri Lexemes'e bölmek için str1 Bu çizginin başlangıcını göstermelidir. Sonraki çağrıların bir parametre olarak işlevi üzerine str1 Sıfır bir işaretçi kullanmanız gerekir. Bu şekilde tüm çizgi lexemlerde bozulur.

Strtok () işlevine her başvurduğunuzda, farklı ayırıcı setlerini kullanabilirsiniz.

Misal

Bu program, ayırıcıların boşlukları ve virgüllerini sunan levhalarda "çim yeşil, güneş parlar" dizesini kırar. Sonuç olarak ortaya çıktı

HESNERN | YEŞİL | Güneş | Blusters #include #Dahil etmek. İnt ana (geçersiz) (char * p; p \u003d strtok ("yeşil çimen,", ""); printf (p); yapmak (p \u003d strtok ("\\ 0", ","); eğer (p) Printf ("|% s", p);) iken (p); dönüş 0;)

Sözdizimi:

#Dahil etmek.
Char * Strtok (char * str, const char * Eyl);

Argümanlar:

str, kırık bir dize için bir işaretçidir.
SEP, bir dizi ayırıcı karakter içeren bir dize için bir işaretçidir.

Geri dönüş değeri:

NULL - Str string stresi parçalara bölünemezse.
Çizginin seçilen bölümünün ilk karakterine işaretçi.

Açıklama:

Strtok özelliği, STR argümanının, SEP argümanının gösterdiği dizgede belirtilen ayırıcıların karakterlerinden birinden ayrıldığı çizginin bir sonraki kısmını vurgular. StrTok fonksiyonunun seri çağrısı, parçadaki dize dizesinin (Lexemes) dağılmasına yol açar.

"Strtok işlevini ilk çağırdığınızda, paylaşılan dizgenin (STR) başlangıcı ve bir dize içeren bir dize (SEP) başlangıcını belirtilir. Başlangıçta, StrTok işlevi dönüşümlü olarak dize dizeleri dizesini görüntüler ve SEP ayırıcı dizesinde bulunmayan bir sembolü arar. String String'de, String ucu sembolü sembolden daha erken karşılaşılırsa, SEP dizgisine dahil edilmediğinden, STR dizesini kısmen bölmek mümkün değildir, sıfır işaretçi (null) döndürülür. Böyle bir sembol bulunursa, string str'nin ilk bölümünün başlangıcı olarak kabul edilir. "

Daha sonra, Strtok işlevi, SEP dizesinde bulunan bir sembolü, yani bir ayırıcı arıyor. Böyle bir sembol bulunmazsa, Str Str String'in bir parçadan oluştuğuna ve String String'in sonraki bir şekilde ayrılmasının sıfır işaretçiyi döndüreceğine inanılmaktadır. Böyle bir sembol bulunursa. Sıfır sembolü ile değiştirilir (çizgi sembolünün sonu). Daha sonra, Strtok özelliği, geçerli pozisyonu hatırlar (işaretçi, hattın bir sonraki parçasının aramasının başlayacağı karaktere işaretçi) ve işaretçiyi çizginin ilk seçilen bölümünün başlangıcına geri döndürür.

STRTOK işlevi sıfır olmayan bir işaretçi döndürürse, parçadaki dize dizesinin bölümüne devam edebilirsiniz. Çizgiyi bölmeye devam etmek için, Strtok işlevi yeniden denir, ancak işaretçi için kırık çizgiye göre NULL ilk artış olarak belirtilir. Bu durumda, StrTok işlevi hafızaya alınmış adresden kopmaya devam edecektir. Bölümün algoritması aynı kalacaktır.

Misal:

Örnekte, "TEST1 / TEST2 / TEST3 / TEST4" satırı, Strtok işlevini kullanarak "/" ayırıcı tarafından parçalara ayrılır. Bölümün sonucu konsolda görüntülenir.

Sonuç:

Konsolda Sonuç:


cHAR FAR * FAR _FSTRTOK (Const Char Far * Str1, Const Char Far * Str2)

Açıklama:

Strtok () işlevi, Str1'in gösterdiği dizgedeki bir sonraki Lex'e bir işaretçi döndürür. Str2'nin STR2'nin gösterdiği dizideki semboller, Lex'i belirleyen sınırlayıcılar olarak kullanılır. Lexema bulunmazsa, NULL döndürülür.

Strtok () işlevinin ilk çağrısı sırasında, Str1 aslında bir işaretçi olarak kullanılır. Sonraki zorluklarla, ilk argüman olarak NULL kullanılır. Böylece, tüm dizge lexemlerde kırılabilir.

Strtok () işlevinin Str1'in gösterdiği dizgiyi değiştirdiğini anlamak önemlidir. Her zaman bir Lexeme bulunduğunda, sınırlayıcının bulunduğu yerde, sıfır sembolü yerleştirilir. Böylece, strtok () dizge boyunca hareket ediyor.

Strtok () çağrısı her seferinde, sınırlayıcı kümesini değiştirebilirsiniz.

_Fstrtok () işlevi, söz konusu işlevin uzak versiyonudur.

Aşağıdaki program, "Soyuter, Sunshine Patriot" dizesini, boşlukları ve virgülleri kullanarak sınırlayıcı olarak kopar. Programın bir sonucu olarak, program aşağıdaki türdeki satır oluşturulacaktır: "| Yaz | Asker | | Sunshine | Vatansever. "
#Dahil etmek.
#Dahil etmek.
İnt ana (geçersiz)
{
char * p;
P \u003d strtok ( "Yaz askeri, güneş ışığı vatansever", " " ) ;
printf (p);
yapmak (
P \u003d strtok (" \0 " , ", " ) ;
if (p) printf ("|% s", p);
) (P);
geri dönüş 0;
}

Diğer diğer adlar.

Strtok.

Genel bakış

#Dahil etmek.

char * Strtok (char *str., Const char *dELIM.);
char * strTok_r (char *str., Const char *dELIM., char **saveptr.);

GliBC için Mülkiyet Testleri Makro Gereksinimleri (bkz. Özellik_test_macros.(7)):

strtok_r.(): _Svid_source || _Bsd_source || _POSIX_C_SOURCE\u003e \u003d 1 || _Xopen_source || _Posix_Source.

AÇIKLAMA

İşlev strtok.() Dizeyi sıfır veya daha fazla boş olmayan belirteçler dizisine ayırır. İlk çağrı altında strtok.() Analiz edilen dize argümanda belirtilmelidir. str.. Sonraki her bir aramanda, aynı dizeyi analiz eden, değer str. Boş olmalı.

Argümada dELIM. Satırdaki belirteç ayırıcıları olarak kabul edilen bir bayt kümesi ayarlanır. Arayan farklı çizgileri gösterebilir dELIM. Aynı dizeyi analiz ederken müteakip zorluklarda.

Her arama strtok.() Aşağıdaki belirteci içeren NULL ile biten bir dize için bir işaretçi döndürür. Bu satır bayt ayırıcı içermez. Daha fazla belirteç yoksa, o zaman strtok.() NULL döndürür.

Çağrı sırası strtok.() Bir satırın çalıştırılması, bir sonraki belirteç aramanın başladığı noktayı belirleyen bir işaretçiyi destekler. İlk meydan okuma strtok.() Bu işaretçiyi ilk bayt çizgisine atar. Bir sonraki belirteçin başlangıcı, öne çıkan arama ile belirlenir. str. Bir sonraki bayt ayırıcı değildir. Bayt bulunursa, bir sonraki belirteçin başlangıcı olarak alınır. Böyle bir bayt bulunmazsa, daha fazla belirteç yoktur ve strtok.() NULL'u döndürür (boş bir dize için veya yalnızca bu durumda ayırıcılardan oluşan, ilk arama yapılırken NULL geri döner strtok.()).

Her Tokeny'nin sonu, bayt ayırıcı bulunana veya nihai bayt null ("\\ 0") olana kadar bulunan bir arama için bir arama. Bayt ayırıcı bulunursa, mevcut belirteçleri tamamlamak için boş bir baytla değiştirilir ve strtok.() Bir işaretçiyi bir sonraki baytına tutar; Bu işaretçi, bir sonraki belirtiyi ararken ilk nokta olarak kullanılacaktır. Bu durumda strtok.() İşaretçiyi Bulunan Tokenin başlangıcına geri döndürür.

Yukarıdaki açıklamadan, izlenen görünümünde iki veya daha fazla sürekli ayırıcı bayt dizisinin bir ayırıcı olarak kabul edildiğini ve satırın başlangıcındaki veya ucundaki bölücü baytları göz ardı edilir. Başka bir deyişle, belirteçler geri döndü strtok.() - Her zaman boş çizgiler değil. Yani, örneğin bir dize varsa " aAA ;; BBB,"Sonra daha sonra zorluklar strtok.() belirtilen satır bölücüleriyle ;, "Çizgileri iade ederdi" aaa"Ve" bBB."Ve sonra boş işaretçi.

İşlev strtok_r.() resifet edilebilir bir sürümdür strtok.(). Argüman saveptr. değişken için bir işaretçi char *içinde kullanılan strtok_r.() Aynı çizgiyi analiz ederken müteakip zorluklar arasındaki bağlamı hesaba katın.

İlk çağrı altında strtok_r.() Değeri str. analiz edilen dizgiyi ve değeri belirtmelidir saveptr. göz ardı edildi. Daha sonra değeri arar str. Boş olmalı ve değer saveptr. önceki aramanın anından itibaren değişmemelidir.

Aynı zamanda, farklı çizgiler çoklu başlatmalarda analiz edilebilir. strtok_r.() çeşitli argümanlar ile saveptr..

Geri dönüş değeri

Fonksiyonlar strtok.() BEN. strtok_r.() İşaretçiyi daha fazla belirteç yoksa, işaretçiyi bir sonraki belirteç veya null'a döndürün.

Öznitellikler

Bu bölümün şartlarının açıklaması, bkz. Öznitellikler.(7).
Arayüz Öznitelik Değer vermek
strtok.() konularda emin olungüvensiz (MT-Unsafe Race: Strtok)
strtok_r.() konularda emin olunzararsız (MT-SAFE)

UYMA

strtok.() POSIX.1-2001, POSIX.1-2008, C89, C99, SVR4, 4.3BSD. strtok_r.() Posix.1-2001, POSIX.1-2008.

Kusurlar

Bu işlevleri dikkatli kullanın. Bunu dikkate al: * Bu işlevler ilk argümanlarını değiştirir. * Bu işlevler sabit dizelerle kullanılamaz. * Bayt ayırıcısının kimliği kaybolur. * İşlevi analiz ederken strtok.() Statik tamponu kullanır, bu nedenle dişler için güvenli değildir. Kullanmak strtok_r.() bu durumda.

MİSAL

Aşağıda sunulan program, neden olan iç içe döngüleri kullanır. strtok_r.() Dizgiyi belirteçlerinin bileşenlerine bölmek için. İlk parametrede komut satırı Analiz edilen dize ayarlandı. İkinci parametrede, bayt (lar), dizeyi "kompozit" belirteçlere bölmek için kullanılan bir ayırıcıdır. Üçüncü parametre, "kompozit" belirteçleri verimli olarak ayırmak için kullanılan ayırıcı bayt (lar) gösterir.

Programın çıktısının sonuçları örneği:

$ ./a.out "a / bbb /// cc; xxx: yyy:" ":;" "/" 1: A / BBB /// CC -\u003e A -\u003e BBB -\u003e CC 2: XXX -\u003e XXX 3: YYY -\u003e YYY

Kaynak Kod Programı

#Dahil etmek. #Dahil etmek. #Dahil etmek. İnt ana (int argc, char * argv) (char * str1, * str2, * belirteci, * SUBTTOKT; char * saveptr1, * saveptr2; int j; eğer (argc! \u003d 4) (fprintf (stderr, "kullanımı:% S String Delim Subdelim \\ n ", argv); (Exit_Failure);) (J \u003d 1, STR1 \u003d ARGV ;; J ++, STR1 \u003d NULL) (TOEN \u003d STRTOK_R (STR1, Argv, & SavePtr1); (token \u003d \u003d null) kopma; printf ("% d:% s \\ n", j, jeton); (str2 \u003d jeton ;; str2 \u003d null) (SubToken \u003d Strtok_r (STR2, Argv, & SavePtr2); (subtoken \u003d\u003d null) kopma; printf ("-\u003e% s \\ n", alt tendi);)) çıkış (exit_success);)

Kullanan bir programın başka bir örneği strtok.() Içinde bulunabilir getaddrinfo_a.(3).