قائمة الطعام
مجانا
التسجيل
الصفحة الرئيسية  /  مشاكل/ وصف Strtok ق ج. man strtok_r (3): استرجاع العناصر (الرموز) من سلسلة

وصف Strtok s c. man strtok_r (3): استرجاع العناصر (الرموز) من سلسلة

4 إجابات

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

والنتيجة الطبيعية المهمة هي أنه لا يمكنك استخدام strtok على حرف ثابت * "hello world" ؛ نظرًا لأنك ستحصل على انتهاك وصول عند تغيير محتويات سلسلة الأحرف الثابتة.

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

مثال. إذا كان لديك "this، is، a string" ، فإن الاستدعاءات المتتالية لـ strtok ستولد مؤشرات مثل هذه (القيمة ^ ​​هي القيمة المرجعة). لاحظ أنه يتم إضافة "\ 0" حيث توجد الرموز المميزة ؛ هذا يعني انه سلسلة المصدرتغير:

T الخاص به ، هو ، a ، سلسلة \ 0 هذه ، a ، سلسلة هذه \ 0 هي ، a ، سلسلة \ 0 هذا ^ هذا \ 0 هو \ 0 a ، سلسلة \ 0 هي ^ هذا \ 0 هي \ 0 a \ سلسلة 0 \ 0 a ^ this \ 0 \ 0 a \ 0 string \ 0 string ^

أتمنى أن يكون هذا منطقيًا.

تخزن الوظيفة strtok () البيانات بين المكالمات. يستخدم هذه البيانات عند استدعائها بمؤشر NULL.

يتم تخزين النقطة التي تم عندها العثور على الرمز المميز الأخير داخليًا بواسطة وظيفة سيتم استخدامها في المكالمة التالية (لا يلزم تنفيذ خاص بالمكتبة لمنع فشل البيانات).

تحافظ strtok على الحالة الداخلية. عندما تستدعيها بـ non-NULL ، فإنها تعيد تهيئة نفسها لاستخدام السلسلة التي توفرها. عندما تستدعيها بـ NULL ، فإنها تستخدم تلك السلسلة وأي حالة أخرى تتلقاها حاليًا لإرجاع الرمز المميز التالي.

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

تقوم وظيفة strtok بتخزين البيانات في متغير ثابت داخلي يتم مشاركته بين جميع مؤشرات الترابط.

من أجل سلامة الخيط ، يجب استخدام strtok_r

ألقِ نظرة على الحرف الثابت * أخيرًا ؛

Char * strtok (s، delim) تسجيل الأحرف ؛ سجل const char * delim ؛ (سجل char * spanp ؛ سجل int c ، sc ؛ char * tok ؛ static char * last ؛ if (s == NULL && (s = last) == NULL) return (NULL) ؛ / * * تخطي (سبان) بادئة المحددات (s + = strspn (s ، delim) ، نوع من). * / cont: c = * s ++ ؛ لـ (spanp = (char *) delim ؛ (sc = * spanp ++)! = 0 ؛) (if (c == sc) goto cont؛) if (c == 0) (/ * لا توجد أحرف غير محددة * / last = NULL؛ return (NULL)؛) tok = s - 1؛ / * * Scan token (البحث عن المحددات: s + = strcspn (s، delim) ، نوع من). * لاحظ أن delim يجب أن يحتوي على NUL واحد ؛ نتوقف إذا رأينا ذلك أيضًا. * / for (؛؛) (c = * s + +؛ spanp = (char *) delim؛ do (if ((sc = * spanp ++) == c) (if (c == 0) s = NULL؛ else s [-1] = 0 ؛ last = s ؛ return (tok)؛)) while (sc! = 0)؛) / * لم يتم الوصول إليها * /)

للمشاركه

#تضمن char * strtok (char * شارع 1، حرف كونستري * str2);

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

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

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

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

مثال

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

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

بناء الجملة:

#تضمن
char * strtok (char * str، const char * sep) ؛

الحجج:

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

القيمة المعادة:

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

وصف:

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

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

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

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

مثال:

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

نتيجة:

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


char far * far _fstrtok (const char far * str1، const char far * str2)

وصف:

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

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

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

في كل مرة تقوم فيها باستدعاء strtok () ، يمكنك تغيير مجموعة المحددات.

وظيفة _fstrtok () هي نسخة FAR من الوظيفة المعنية.

يقوم البرنامج التالي بتقسيم السلسلة النصية "الجندي الصيفي ، الشمس المشرقة الوطني" إلى رموز ، باستخدام المسافات والفواصل كمحددات. نتيجة لعملية البرنامج ، سيتم إنشاء سطر من النموذج التالي: “The | الصيف | جندي | في | أشعة الشمس | باتريوت ".
#تضمن
#تضمن
int main (باطل)
{
شار * ع ؛
ع = strtok ( "جندي الصيف ، وطن الشمس المشرقة", " " ) ;
printf (ع) ؛
فعل (
p = strtok (" \0 " , ", " ) ;
إذا (p) printf ("|٪ s" ، p) ؛
) بينما (ع) ؛
العودة 0 ؛
}

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

strtok

نظرة عامة

#تضمن

char * strtok (char *شارع، حرف كونستري *دليم);
char * strtok_r (char *شارع، حرف كونستري *دليم، شار **سافيبتر);

متطلبات الماكرو لاختبار الملكية لـ 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() مع فواصل الأسطر المحددة " ;, "هل تعيد الخطوط" أأ" و " ب ب"متبوعًا بمؤشر فارغ.

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

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

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

قيمة الإرجاع

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

صفات

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

امتثال

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

عيوب

استخدم هذه الوظائف بعناية. لاحظ أن: * هذه الدالات تعدل وسيطتها الأولى. * لا يمكن استخدام هذه الوظائف مع سلاسل ثابتة. * تم فقد هوية بايت المحدد. * عند الاعراب وظيفة 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) ؛) لـ (j = 1، str1 = argv ؛؛ j ++، str1 = NULL) (الرمز المميز = strtok_r (str1، argv، & saveptr1) ؛ إذا (الرمز = = NULL) كسر ؛ printf ("٪ d:٪ s \ n"، j، token) ؛ لـ (str2 = token ؛؛ str2 = NULL) (subtoken = strtok_r (str2، argv، & saveptr2) ؛ إذا (suboken == NULL) break؛ printf ("->٪ s \ n"، subtoken) ؛)) خروج (EXIT_SUCCESS) ؛)

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