وظائف سترتوك. كيف تعمل الدالة strtok في لغة C؟ مثال: كود مصدر البرنامج

الاسم المستعار الآخر

com.strtok

مراجعة

#يشمل

شار *سترتوك (شار *شارع، حرف ثابت *delim);
شار *strtok_r(شار *شارع، حرف ثابت *delim،شار**saveptr);

متطلبات ماكرو اختبار الخاصية لـ glibc (انظر feature_test_macros(7)):

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

وصف

وظيفة com.strtok() يقسم السلسلة إلى سلسلة من صفر أو أكثر من الرموز غير الفارغة. عند المكالمة الأولى com.strtok() يجب تحديد السلسلة المراد تحليلها في الوسيطة شارع. في كل استدعاء لاحق يقوم بتوزيع نفس السلسلة، القيمة شارعيجب أن تكون فارغة.

في الحجة delimيتم تحديد مجموعة من البايتات التي تعتبر فواصل رمزية في السلسلة التي تم تحليلها. يمكن للمتصل تحديد خطوط مختلفة في delimفي المكالمات اللاحقة عند تحليل نفس السلسلة.

كل مكالمة com.strtok() يُرجع مؤشرًا إلى سلسلة منتهية بقيمة خالية تحتوي على الرمز المميز التالي. لا يتضمن هذا السطر بايت محدد. إذا لم يكن هناك المزيد من الرموز، ثم com.strtok() ترجع NULL.

تسلسل المكالمة com.strtok()، التي تعمل على سلسلة واحدة، تحتفظ بمؤشر يحدد النقطة التي يبدأ عندها البحث عن الرمز المميز التالي. اول مكالمة com.strtok() يعين هذا المؤشر مرجعًا للبايت الأول من السلسلة. يتم تحديد بداية الرمز المميز التالي من خلال البحث للأمام شارعالبايت التالي ليس محددًا. إذا تم العثور على بايت، فسيتم اعتباره بداية الرمز المميز التالي. إذا لم يتم العثور على مثل هذا البايت، فلن يكون هناك المزيد من الرموز و com.strtok() تُرجع NULL (بالنسبة إلى سلسلة فارغة أو محددة، وفي هذه الحالة سيتم إرجاع NULL في المرة الأولى التي يتم استدعاؤها com.strtok()).

يتم العثور على نهاية كل رمز مميز من خلال البحث الأمامي حتى يتم العثور على بايت محدد أو بايت فارغ زائدة ("\0"). إذا تم العثور على بايت محدد، فسيتم استبداله ببايت فارغ لإنهاء الرمز المميز الحالي، و com.strtok() يخزن مؤشرًا إلى البايت التالي؛ سيتم استخدام هذا المؤشر كنقطة بداية عند البحث عن الرمز المميز التالي. في هذه الحالة com.strtok() يُرجع مؤشرًا إلى بداية الرمز المميز الذي تم العثور عليه.

من الوصف أعلاه، يترتب على ذلك أن تسلسل اثنين أو أكثر من وحدات البايت المحددة المتجاورة في السطر الذي يتم فحصه يعتبر محددًا واحدًا، ويتم تجاهل وحدات البايت المحددة في بداية السلسلة أو نهايتها. وبعبارة أخرى، عادت الرموز com.strtok() - سلاسل غير فارغة دائمًا. وهذا على سبيل المثال إذا كان هناك خط " أأ؛؛ببب،"، ثم المكالمات اللاحقة com.strtok() مع فواصل الأسطر المحددة " ;, "سيعود السلاسل" aaa" و " bbb"ثم مؤشر فارغ.

وظيفة strtok_r() هو الإصدار المعاد إدخاله com.strtok(). دعوى saveptrهو مؤشر إلى متغير شار *والذي يستخدم داخليا strtok_r() لمراعاة السياق بين الاستدعاءات اللاحقة عند تحليل نفس السلسلة.

عند المكالمة الأولى strtok_r() معنى شارعيجب أن تشير إلى السلسلة التي يتم تحليلها، والقيمة saveptrتم تجاهله. على المكالمات اللاحقة القيمة شارعيجب أن تكون فارغة والقيمة saveptrلا ينبغي أن تتغير منذ المكالمة السابقة.

يمكن تحليل صفوف مختلفة في وقت واحد عبر عمليات تشغيل متعددة strtok_r() مع حجج مختلفة saveptr.

قيمة الإرجاع

المهام com.strtok() و strtok_r() قم بإرجاع المؤشر إلى الرمز المميز التالي أو NULL إذا لم يكن هناك المزيد من الرموز المميزة.

صفات

للحصول على وصف للمصطلحات في هذا القسم، راجع صفات(7).
واجهه المستخدم يصف معنى
com.strtok() ضرر في المواضيعغير آمن (سباق MT-غير الآمن: strtok)
strtok_r() ضرر في المواضيعغير ضار (MT-آمن)

امتثال

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

عيوب

استخدم هذه الميزات بحذر. يرجى ملاحظة ما يلي: * تقوم هذه الوظائف بتعديل وسيطتها الأولى. * لا يمكن استخدام هذه الوظائف مع سلاسل ثابتة. * تم فقدان هوية البايت الفاصل. * عند تحليل الوظيفة com.strtok() يستخدم مخزنًا مؤقتًا ثابتًا، وبالتالي فهو غير آمن لمؤشر الترابط. يستخدم strtok_r() في هذه الحالة.

مثال

يستخدم البرنامج أدناه حلقات متداخلة للاتصال strtok_r() لتقسيم السلسلة إلى الرموز المكونة لها. في المعلمة الأولى سطر الأوامريتم تحديد السلسلة المراد تحليلها. تحدد المعلمة الثانية البايت (الوحدات) الفاصلة، والتي يتم استخدامها لتقسيم السلسلة إلى رموز مميزة "مركبة". تحدد المعلمة الثالثة البايت (الوحدات) الفاصلة، والتي يتم استخدامها لفصل الرموز المميزة "المركبة" إلى رموز فرعية.

مثال على مخرجات البرنامج:

$./a.out "a/bbb///cc;xxx:yyy:" ":;" "/" 1: a/bbb///cc --> a --> bbb --> cc 2: xxx --> xxx 3: yyy --> yyy

كود مصدر البرنامج

#يشمل #يشمل #يشمل int main(int argc, char *argv) ( char *str1, *str2, *token, *subtoken; char *saveptr1, *saveptr2; int j; if (argc != 4) ( fprintf(stderr, "Usage: % s string delim subdelim\n"، argv)؛exit(EXIT_FAILURE); ) for (j = 1, str1 = argv; ; j++, str1 = NULL) ( token = strtok_r(str1, argv, &saveptr1); if (token = = NULL) Break; printf("%d: %s\n", j, token); for (str2 = token; ; str2 = NULL) ( subtoken = strtok_r(str2, argv, &saveptr2); if (subtoken == NULL) استراحة؛ printf(" --> %s\n"، رمز فرعي)؛ ) ) خروج(EXIT_SUCCESS); )

مثال آخر لبرنامج يستخدم com.strtok()، يمكن العثور عليها في getaddrinfo_a(3).

تقوم الدالة strtok() بإرجاع مؤشر إلى الرمز المميز التالي في السلسلة المشار إليها بواسطة str1. الأحرف التي تشكل السلسلة التي تتناولها str2 هي المحددات التي تحدد الرمز المميز. إذا لم يكن هناك رمز مميز لإرجاعه، فسيتم إرجاع مؤشر فارغ.

في الإصدار C99، يتم تطبيق مؤهل التقييد على معلمات str1 وstr2.

لتقسيم سلسلة إلى رموز مميزة، في المرة الأولى التي يتم فيها استدعاء الدالة strtok()، يجب أن تشير المعلمة str1 إلى بداية السلسلة. يجب أن تستخدم الاستدعاءات اللاحقة للوظيفة مؤشرًا فارغًا كمعلمة str1. في هذه الحالة، سيتم تعديل السلسلة الكاملة في كل مرة يتم فيها استدعاء الدالة.

يمكن لكل استدعاء للدالة strtok() استخدام مجموعة مختلفة من محددات الرمز المميز.

توفر الدالة strtok() وسيلة لتقليص السلسلة إلى الأجزاء المكونة لها. على سبيل المثال، يقوم البرنامج التالي بتعيين السلسلة "واحد واثنين وثلاثة".

#يشمل #يشمل int main(void) char *p; p = strtok("واحد واثنان وثلاثة.", "); printf(ع); do ( p = strtok(NULL, ",. "); if(p) printf("|%s", p); ) while(p), return 0; )

نتيجة هذا البرنامج هي كما يلي.

واحد | اثنان | و | ثلاثة

لاحظ كيف وظيفة سترتوك() يتم استدعاؤها أولاً باستخدام السلسلة الأصلية، لكن الاستدعاءات اللاحقة لها تستخدم NULL كوسيطة أولى. تحتفظ الدالة strtok() بمؤشر داخلي للسلسلة التي تتم معالجتها. إذا كانت الوسيطة الأولى لـ strtok() تشير إلى سلسلة، فسيتم تعيين المؤشر الداخلي على بداية تلك السلسلة. إذا كانت الوسيطة الأولى NULL، فستستمر الدالة strtok()‎ في معالجة السلسلة السابقة، بدءًا من الموضع الذي تم تعلمه في الخطوة السابقة، وتقدم المؤشر الداخلي عند استرداد الرمز المميز التالي. وبالتالي، فإن الدالة strtok() "تجتاز" السلسلة بأكملها. لاحظ أيضًا كيف تتغير سلسلة المحدد عند الاستدعاءات الأولى واللاحقة للوظيفة. قد يتم تعريف المحددات بشكل مختلف لكل مكالمة.

#يشمل شار *سترتوك (شار * str1، حرف ثابت * str2);

تقوم الدالة strtok() بإرجاع مؤشر إلى الرمز المميز التالي في السلسلة التي تتناولها المعلمة str1. الأحرف التي تشكل السلسلة التي تتناولها المعلمة str2، هي المحددات التي تحدد الرمز المميز. إذا لم يكن هناك رمز مميز لإرجاعه، فسيتم إرجاع مؤشر فارغ.

في الإصدار C99 إلى المعلمات str1و str2يتم تطبيق مؤهل التقييد.

لتقسيم سلسلة إلى رموز مميزة، في المرة الأولى التي تقوم فيها باستدعاء strtok()، المعلمة str1يجب أن نشير إلى بداية هذا السطر. في الاستدعاءات اللاحقة للوظيفة كمعلمة str1تحتاج إلى استخدام مؤشر فارغ. بهذه الطريقة، يتم تقسيم السلسلة بأكملها إلى رموز مميزة.

يمكن لكل استدعاء للدالة strtok() استخدام مجموعة مختلفة من المحددات.

مثال

يقسم هذا البرنامج سلسلة "العشب أخضر، والشمس مشرقة" إلى رموز مفصولة بمسافات وفواصل. ستكون النتيجة

العشب|يتحول إلى اللون الأخضر|الشمس|يتضمن اللمعان #يشمل int main(void) ( char *p; p = strtok("العشب أخضر، والشمس مشرقة"، " "); printf(p); do ( p = strtok("\0", ", ") ; إذا(p ) printf("|%s", p); ) while(p); إرجاع 0; )

بناء الجملة:

#يشمل
char *strtok(char *str, const char *sep);

الحجج:

str - مؤشر إلى السلسلة المراد تقسيمها.
sep - مؤشر إلى سلسلة تحتوي على مجموعة من الأحرف المحددة.

قيمة الإرجاع:

NULL - إذا كان لا يمكن تقسيم السلسلة النصية إلى أجزاء.
مؤشر إلى الحرف الأول للجزء المحدد من السلسلة.

وصف:

تحدد الدالة strtok الجزء التالي من السلسلة المشار إليها بواسطة الوسيطة str، مفصولة بأحد الأحرف المحددة في السلسلة المشار إليها بواسطة الوسيطة sep. تؤدي الاستدعاءات المتتالية إلى الدالة strtok إلى تقسيم السلسلة النصية إلى أجزاء (رموز مميزة).

"يحدد الاستدعاء الأول للدالة strtok بداية السلسلة المراد تقسيمها (str) وبداية السلسلة التي تحتوي على فواصل (sep). تبدأ الدالة strtok بالبحث في أحرف السلسلة النصية الواحدة تلو الأخرى والبحث عن حرف غير موجود في السلسلة المحددة sep. إذا تمت مواجهة نهاية السطر في السلسلة النصية قبل العثور على حرف غير مضمن في السلسلة sep، فلا يمكن تقسيم السلسلة النصية إلى أجزاء ويتم إرجاع مؤشر فارغ (NULL). إذا تم العثور على مثل هذا الحرف، فسيتم اعتباره بداية الجزء الأول من السلسلة النصية."

بعد ذلك، تبحث الدالة strtok عن الفاصل، أي الحرف المضمن في السلسلة sep. إذا لم يتم العثور على مثل هذا الحرف، فسيتم اعتبار السلسلة النصية مكونة من جزء واحد وستؤدي الانقسامات اللاحقة للسلسلة إلى إرجاع مؤشر فارغ. إذا تم العثور على مثل هذا الرمز. ثم يتم استبداله بحرف فارغ (حرف نهاية السطر). بعد ذلك، تتذكر وظيفة strtok الموضع الحالي (مؤشر إلى الحرف الذي سيبدأ منه البحث عن الجزء التالي من السطر) وترجع مؤشرًا إلى بداية الجزء الأول المحدد من السطر.

إذا أعادت الدالة strtok مؤشرًا غير فارغ، فيمكنك الاستمرار في تقسيم السلسلة إلى أجزاء. لمواصلة تقسيم السلسلة، يتم استدعاء الدالة strtok مرة أخرى، ولكن بدلاً من الإشارة إلى السلسلة المراد تقسيمها، يتم تحديد NULL كإضافة أولى. في هذه الحالة، ستستمر الدالة strtok في الانفصال عن العنوان الذي تم تذكره. ستبقى خوارزمية التقسيم كما هي.

مثال:

في المثال، يتم تقسيم السلسلة "test1/test2/test3/test4" إلى أجزاء باستخدام المحدد "/" باستخدام الدالة strtok. يتم إخراج نتيجة الانقسام إلى وحدة التحكم.

نتيجة:

إخراج وحدة التحكم:





قمة