توابع strtok تابع strtok در C چگونه کار می کند؟ مثال: کد منبع برنامه

نام مستعار دیگر

strtok

مرور

#عبارتند از

char *strok(char *خ, const char *دیلیم);
char *strtok_r(char *خ, const char *دیلیم، کاراکتر **saveptr);

الزامات ماکرو تست دارایی برای glibc (نگاه کنید به feature_test_macros(7)):

strtok_r(): _SVID_SOURCE || _BSD_SOURCE || _POSIX_C_SOURCE >= 1 || _XOPEN_SOURCE || _POSIX_SOURCE

شرح

تابع strtok() یک رشته را به دنباله ای از توکن های غیر خالی صفر یا بیشتر تقسیم می کند. در اولین تماس strtok() رشته مورد تجزیه و تحلیل باید در آرگومان مشخص شود خ. در هر فراخوان بعدی که همان رشته را تجزیه می کند، مقدار خباید NULL باشد.

در استدلال دیلیممجموعه ای از بایت ها مشخص شده است که جداکننده نشانه در رشته تحلیل شده در نظر گرفته می شوند. تماس گیرنده می تواند خطوط مختلفی را در آن مشخص کند دیلیمدر فراخوانی های بعدی هنگام تجزیه همان رشته.

هر تماس strtok() یک اشاره گر را به رشته تهی که حاوی نشانه بعدی است برمی گرداند. این خط شامل یک بایت جداکننده نیست. اگر توکن دیگری وجود ندارد، پس strtok() NULL را برمی گرداند.

دنباله تماس strtok() که بر روی یک رشته عمل می کند، یک اشاره گر را حفظ می کند که نقطه شروع جستجوی نشانه بعدی را مشخص می کند. اولین تماس strtok() این اشاره گر را به اولین بایت رشته نسبت می دهد. شروع توکن بعدی با جستجو به جلو مشخص می شود خبایت بعدی جداکننده نیست. اگر یک بایت پیدا شود، به عنوان ابتدای توکن بعدی در نظر گرفته می شود. اگر چنین بایتی پیدا نشد، دیگر توکن و strtok() NULL را برمی گرداند (برای یک رشته خالی یا محدود، در این صورت NULL اولین باری که فراخوانی می شود برگردانده می شود. strtok()).

انتهای هر نشانه با جستجوی رو به جلو پیدا می شود تا زمانی که یک بایت جداکننده یا یک بایت تهی انتهایی ("\0") پیدا شود. اگر یک بایت جداکننده پیدا شود، با یک بایت تهی جایگزین می شود تا توکن فعلی خاتمه یابد، و strtok() یک اشاره گر به بایت بعدی را ذخیره می کند. این اشاره گر به عنوان نقطه شروع در هنگام جستجوی نشانه بعدی استفاده می شود. در این مورد strtok() یک اشاره گر را به ابتدای نشانه پیدا شده برمی گرداند.

از توضیحات بالا، نتیجه می‌شود که دنباله‌ای از دو یا چند بایت جداکننده به‌هم پیوسته در خطی که اسکن می‌شود، یک جداکننده واحد در نظر گرفته می‌شود و بایت‌های جداکننده در ابتدا یا انتهای رشته نادیده گرفته می‌شوند. به عبارت دیگر، توکن ها بازگشتند strtok() - رشته های همیشه غیر خالی. به عنوان مثال، اگر یک خط وجود دارد " aaa;;bbb,"، سپس تماس های بعدی strtok() با جداکننده های خط داده شده " ;, "رشته ها را برمی گرداند" aaa"و" bbb" و سپس یک اشاره گر تهی.

تابع strtok_r() نسخه ورودی مجدد است strtok(). بحث و جدل saveptrیک اشاره گر به یک متغیر است کاراکتر *که به صورت داخلی استفاده می شود strtok_r() برای در نظر گرفتن زمینه بین فراخوانی های بعدی هنگام تجزیه همان رشته.

در اولین تماس strtok_r() معنی خباید به رشته در حال تجزیه و مقدار اشاره کند saveptrنادیده گرفته شده است. در تماس های بعدی مقدار خباید NULL و مقدار باشد saveptrاز تماس قبلی نباید تغییر کند.

ردیف های مختلف را می توان به طور همزمان در چندین اجرا تجزیه و تحلیل کرد strtok_r() با استدلال های مختلف saveptr.

ارزش بازگشتی

کارکرد strtok() و strtok_r() یک اشاره گر را به نشانه بعدی یا NULL برگردانید اگر توکن دیگری وجود نداشت.

ویژگی های

برای توضیح اصطلاحات در این بخش، نگاه کنید به ویژگی های(7).
رابط صفت معنی
strtok() بی ضرر بودن در نخ هاناامن (MT-ناامن مسابقه:strtok)
strtok_r() بی ضرر بودن در نخ هابی ضرر (MT-Safe)

انطباق

strtok() POSIX.1-2001، POSIX.1-2008، C89، C99، SVr4، 4.3BSD. strtok_r() POSIX.1-2001، POSIX.1-2008.

عیوب

از این ویژگی ها با احتیاط استفاده کنید. لطفاً توجه داشته باشید که: * این توابع اولین آرگومان خود را تغییر می دهند. * این توابع را نمی توان با رشته های ثابت استفاده کرد. * هویت بایت جداکننده از بین رفته است. * هنگام تجزیه و تحلیل تابع strtok() از یک بافر استاتیک استفاده می کند و بنابراین از نظر thread ایمن نیست. استفاده کنید strtok_r() در این مورد.

مثال

برنامه زیر از حلقه های تو در تو برای فراخوانی استفاده می کند strtok_r() برای تقسیم یک رشته به نشانه های تشکیل دهنده آن. در پارامتر اول خط فرمانرشته مورد تجزیه و تحلیل مشخص شده است. پارامتر دوم، بایت(های) جداکننده را مشخص می کند، که برای تقسیم رشته به توکن های "کامپوزیت" استفاده می شود. سومین پارامتر، بایت(های) جداکننده را مشخص می کند، که برای جداسازی توکن های "کامپوزیت" به زیر نشانه ها استفاده می شود.

نمونه ای از خروجی برنامه:

$./a.out "a/bbb///cc;xxx:yyyy:" ":;" "/" 1: a/bbb///cc --> a --> bbb --> سی سی 2: xxx --> xxx 3: سال --> سال

کد منبع برنامه

#عبارتند از #عبارتند از #عبارتند از اصلی s رشته delim subdelim\n"، argv؛ exit(EXIT_FAILURE); ) برای (j = 1, str1 = argv; ; j++, str1 = NULL) (token = strtok_r(str1, argv, &saveptr1)؛ if (token = = NULL) break؛ printf("%d: %s\n"، j، نشانه)؛ برای (str2 = نشانه؛ str2 = NULL) (زیر نشانه = strtok_r(str2، argv، &saveptr2)؛ اگر (زیر نشانه == NULL) شکست؛ printf(" --> %s\n"، زیر نشانه)؛ ) ) خروج (EXIT_SUCCESS)؛ )

مثال دیگری از برنامه ای که با استفاده از strtok()، را می توان در یافت getaddrinfo_a(3).

تابع ()strtok یک اشاره گر را به نشانه بعدی در رشته ای که توسط str1 به آن اشاره شده است برمی گرداند. کاراکترهایی که رشته آدرس دهی شده توسط str2 را تشکیل می دهند، جداکننده هایی هستند که توکن را تعریف می کنند. اگر نشانه ای برای بازگشت وجود نداشته باشد، یک اشاره گر تهی برگردانده می شود.

در نسخه C99، محدودیت محدودیت برای پارامترهای str1 و str2 اعمال می شود.

برای تقسیم یک رشته به نشانه، اولین باری که strtok() فراخوانی می شود، پارامتر str1 باید به ابتدای رشته اشاره کند. فراخوانی های بعدی تابع باید از یک نشانگر تهی به عنوان پارامتر str1 استفاده کند. در این حالت، هر بار که تابع فراخوانی شود، رشته کامل تغییر خواهد کرد.

هر فراخوانی تابع sttok() می تواند از مجموعه متفاوتی از جداکننده های نشانه استفاده کند.

تابع ()strtok وسیله ای برای کاهش یک رشته به قسمت های تشکیل دهنده آن فراهم می کند. به عنوان مثال، برنامه زیر رشته "یک، دو و سه" را نشانه گذاری می کند.

#عبارتند از #عبارتند از int main(void) char *p; p = strtok("یک، دو و سه."، ""); printf(p); do ( p = strtok(NULL, ",. "); if(p) printf("|%s", p); ) while(p)، بازگشت 0; )

نتیجه این برنامه به شرح زیر است.

یک | دو | و | سه

توجه کنید که چگونه تابع strtok() ابتدا با رشته اصلی فراخوانی می شود، اما فراخوانی های بعدی از NULL به عنوان اولین آرگومان استفاده می شود. تابع sttok() یک اشاره گر داخلی به رشته در حال پردازش نگه می دارد. اگر اولین آرگومان strtok() به یک رشته اشاره کند، نشانگر داخلی در ابتدای آن رشته تنظیم می شود. اگر آرگومان اول NULL باشد، strtok() به پردازش رشته قبلی ادامه می دهد، از موقعیتی که در مرحله قبل یاد گرفتیم شروع می کند و با بازیابی نشانه بعدی، نشانگر داخلی را پیش می برد. بنابراین، تابع ()strtok کل رشته را "پیمایش" می کند. همچنین توجه کنید که چگونه رشته جداکننده در اولین و بعد از فراخوانی تابع تغییر می کند. جداکننده ها ممکن است برای هر تماس متفاوت تعریف شوند.

#عبارتند از char *strok(char * str1, const char * str2);

تابع ()strtok یک اشاره گر را به نشانه بعدی در رشته آدرس دهی شده توسط پارامتر برمی گرداند. str1. کاراکترهای تشکیل دهنده رشته آدرس دهی شده توسط پارامتر str2، جداکننده هایی هستند که یک توکن را تعریف می کنند. اگر نشانه ای برای بازگشت وجود نداشته باشد، یک اشاره گر تهی برگردانده می شود.

در نسخه C99 به پارامترها str1و str2واجد شرایط محدود اعمال می شود.

برای تقسیم یک رشته به نشانه‌ها، اولین باری که strtok()، پارامتر را فراخوانی می‌کنید str1باید به ابتدای این خط اشاره کرد. در فراخوانی های بعدی تابع به عنوان یک پارامتر str1شما باید از یک اشاره گر تهی استفاده کنید. به این ترتیب کل رشته به توکن ها تقسیم می شود.

هر فراخوانی تابع ()strtok می تواند از مجموعه متفاوتی از جداکننده ها استفاده کند.

مثال

این برنامه رشته "علف سبز است، خورشید می درخشد" را به نشانه هایی که با فاصله و کاما از هم جدا شده اند، می شکند. نتیجه خواهد شد

چمن|سبز می شود|خورشید|درخشش #شامل #عبارتند از int main(void) (char *p; p = strtok("علف سبز است، خورشید می درخشد"، ""); printf(p); do (p = strtok("\0"، "، ") ; if(p ) printf("|%s"، p); ) while(p); return 0; )

نحو:

#عبارتند از
char *strtok(char *str, const char *sep);

استدلال ها:

str - اشاره گر به رشته ای که باید تقسیم شود.
sep - اشاره گر به رشته ای حاوی مجموعه ای از کاراکترهای جداکننده.

ارزش برگشتی:

NULL - اگر رشته رشته را نتوان به بخش تقسیم کرد.
یک اشاره گر به اولین کاراکتر قسمت انتخاب شده از رشته.

شرح:

تابع strtok قسمت بعدی رشته را انتخاب می کند که با آرگومان str به آن اشاره شده است، که توسط یکی از کاراکترهای جداکننده مشخص شده در رشته ای که با آرگومان sep به آن اشاره شده است، از هم جدا شده است. فراخوانی های متوالی تابع strtok منجر به تقسیم رشته str به قطعات (توکن) می شود.

اولین فراخوانی تابع strtok شروع رشته ای را که باید تقسیم شود (str) و ابتدای رشته حاوی جداکننده ها (sep) را مشخص می کند. تابع strtok با نگاه کردن به کاراکترهای رشته str در یک زمان و جستجوی کاراکتری که در رشته محدود شده sep وجود ندارد شروع می شود. اگر در string str با کاراکتر انتهای خط قبل از یافتن کاراکتری که در رشته sep وجود ندارد مواجه شد، آنگاه نمی توان رشته رشته را به قطعات تقسیم کرد و یک اشاره گر تهی (NULL) برگردانده می شود. اگر چنین کاراکتری پیدا شود، ابتدای قسمت اول رشته رشته در نظر گرفته می شود."

سپس، تابع strtok به دنبال جداکننده، یعنی کاراکتر موجود در رشته sep می گردد. اگر چنین کاراکتری پیدا نشد، رشته str از یک قسمت در نظر گرفته می‌شود و تقسیم‌های بعدی رشته str یک نشانگر تهی را برمی‌گرداند. اگر چنین نمادی یافت شود. سپس با یک کاراکتر پوچ (نویسه پایان خط) جایگزین می شود. در مرحله بعد، تابع strtok موقعیت فعلی را به خاطر می آورد (نشانگر به کاراکتری که جستجو برای قسمت بعدی رشته از آن آغاز می شود) و یک اشاره گر را به ابتدای اولین قسمت انتخاب شده رشته برمی گرداند.

اگر تابع strtok یک اشاره گر غیر تهی برگرداند، می توانید به تقسیم رشته به قطعات ادامه دهید. برای ادامه تقسیم رشته، تابع sttok دوباره فراخوانی می شود، اما به جای اشاره گر به رشته ای که باید تقسیم شود، NULL به عنوان اولین تقویت کننده مشخص می شود. در این حالت، تابع strtok از آدرس به خاطر سپرده شده جدا می شود. الگوریتم پارتیشن بندی ثابت خواهد ماند.

مثال:

در مثال، رشته “test1/test2/test3/test4” با استفاده از جداکننده “/” با استفاده از تابع sttok به قطعات تقسیم می‌شود. نتیجه تقسیم به کنسول خروجی می شود.

نتیجه:

خروجی کنسول:





بالا