التعامل مع سلسلة C
| مكتبة سي القياسية (libc) |
|---|
| المواضيع العامة |
| عناوين متنوعة |
تحتوي لغة البرمجة C على مجموعة من الوظائف التي تنفذ عمليات على السلاسل (سلاسل الأحرف وسلاسل البايتات) في مكتبتها القياسية . يتم دعم عمليات مختلفة، مثل النسخ والتسلسل والتجزئة والبحث. بالنسبة لسلاسل الأحرف، تستخدم المكتبة القياسية الاتفاقية التي تنص على أن السلاسل منتهية بعلامة فارغة : يتم تمثيل سلسلة من n حرفًا كمصفوفة من n + 1 عنصر، يكون آخرها " حرف NUL " بقيمة عددية 0.
الدعم الوحيد للسلاسل في لغة البرمجة الصحيحة هو أن المترجم يترجم ثوابت السلسلة المقتبسة إلى سلاسل منتهية بعلامة فارغة.
التعاريف
يتم تعريف السلسلة على أنها تسلسل متجاور من وحدات الترميز التي تنتهي بوحدة الترميز الصفرية الأولى (غالبًا ما تسمى وحدة الترميز NUL ). [1] وهذا يعني أن السلسلة لا يمكن أن تحتوي على وحدة الترميز الصفرية، حيث أن أول وحدة يتم رؤيتها تشير إلى نهاية السلسلة. طول السلسلة هو عدد وحدات الترميز قبل وحدة الترميز الصفرية. [1] تكون الذاكرة التي تشغلها السلسلة دائمًا وحدة ترميز واحدة أكثر من الطول، حيث تكون هناك حاجة إلى مساحة لتخزين وحدة الترميز الصفرية.
بشكل عام، يشير مصطلح السلسلة إلى سلسلة حيث تكون وحدة الكود من النوع char، والتي تتكون من 8 بتات بالضبط على جميع الأجهزة الحديثة. يحدد C90 سلاسل عريضة [1] تستخدم وحدة كود من النوع wchar_t، والتي تتكون من 16 أو 32 بت على الأجهزة الحديثة. كان هذا مخصصًا لـ Unicode ولكن من الشائع بشكل متزايد استخدام UTF-8 في السلاسل العادية لـ Unicode بدلاً من ذلك.
يتم تمرير السلاسل إلى الوظائف عن طريق تمرير مؤشر إلى وحدة التعليمات البرمجية الأولى. نظرًا لأن char *و wchar_t *نوعان مختلفان، فإن الوظائف التي تعالج السلاسل العريضة تختلف عن تلك التي تعالج السلاسل العادية ولها أسماء مختلفة.
يتم تحويل حروف السلسلة ( "text"في كود المصدر C) إلى مصفوفات أثناء التجميع. [2] والنتيجة هي مصفوفة من وحدات التعليمات البرمجية تحتوي على جميع الأحرف بالإضافة إلى وحدة التعليمات البرمجية صفرية في النهاية. في C90 L"text"ينتج سلسلة عريضة. يمكن أن تحتوي حرفية السلسلة على وحدة التعليمات البرمجية صفرية (إحدى الطرق هي وضعها \0في المصدر)، ولكن هذا سيؤدي إلى إنهاء السلسلة عند هذه النقطة. سيتم وضع بقية الحرفي في الذاكرة (مع إضافة وحدة تعليمات برمجية صفرية أخرى إلى النهاية) ولكن من المستحيل معرفة أن وحدات التعليمات البرمجية هذه قد تمت ترجمتها من حرفية السلسلة، وبالتالي فإن مثل هذا الكود المصدر ليس حرفيًا سلسلة. [3]
ترميزات الأحرف
تنتهي كل سلسلة عند أول ظهور لوحدة الكود الصفري من النوع المناسب ( charأو ). وبالتالي، يمكن wchar_tلسلسلة البايت ( ) أن تحتوي على أحرف غير NUL في ASCII أو أي امتداد ASCII ، ولكن ليس أحرفًا في ترميزات مثل UTF-16 (على الرغم من أن وحدة الكود المكونة من 16 بت قد تكون غير صفرية، فقد يكون بايتها العالي أو المنخفض صفرًا). يتم تعريف الترميزات التي يمكن تخزينها في سلاسل عريضة بعرض . في معظم التطبيقات، يكون 16 بت على الأقل، وبالتالي يمكن تخزين جميع ترميزات 16 بت، مثل UCS-2 . إذا كان 32 بت، فيمكن تخزين ترميزات 32 بت، مثل UTF-32 . (يتطلب المعيار "نوعًا يحتوي على أي حرف عريض"، وهو ما لم يعد صحيحًا على نظام التشغيل Windows منذ التحول من UCS-2 إلى UTF-16. وقد تم التعرف على هذا باعتباره عيبًا في المعيار وتم إصلاحه في C++.) [4] يضيف C++11 و C11 نوعين بعرض واضح و . [5]char*wchar_twchar_twchar_tchar16_tchar32_t
يمكن استخدام ترميزات العرض المتغير في كل من سلاسل البايت والسلاسل العريضة. يتم قياس طول السلسلة والإزاحات بالبايتات أو wchar_t، وليس بالأحرف، وهو ما قد يربك المبرمجين المبتدئين. غالبًا ما يتم استخدام UTF-8 و Shift JIS في سلاسل البايت C، بينما غالبًا ما يتم استخدام UTF-16 في سلاسل العرض C عندما wchar_tتكون 16 بت. يمكن أن يؤدي قطع السلاسل ذات الأحرف ذات العرض المتغير باستخدام وظائف مثل strncpyإلى إنتاج تسلسلات غير صالحة في نهاية السلسلة. قد يكون هذا غير آمن إذا تم تفسير الأجزاء المقطوعة بواسطة كود يفترض أن المدخلات صالحة.
دعم أحرف Unicode مثل (UTF-8) أو (UTF-16 أو UTF-32، يعتمد على ) هو تنفيذ محدد، [6] وقد يتطلب أن يكون كود المصدر بنفس الترميز، خاصةً حيث قد ينسخ المترجمون فقط أي شيء بين علامات الاقتباس. ستتطلب بعض المترجمين أو المحررين إدخال جميع الأحرف غير ASCII كتسلسلات لكل بايت من UTF-8، و/أو لكل كلمة من UTF-16. منذ C11 (و C++11)، تتوفر بادئة حرفية جديدة تضمن UTF-8 لحرفية سلسلة البايت، كما في . [7] منذ C++20 و C23 ، تمت إضافة نوع مخصص لتخزين أحرف UTF-8 وتم تغيير أنواع الأحرف ذات البادئة u8 وأحرف السلسلة إلى و على التوالي.
char foo[512] = "φωωβαρ";wchar_t foo[512] = L"φωωβαρ";wchar_tchar\xNN\uNNNNu8char foo[512] = u8"φωωβαρ";char8_tchar8_tchar8_t[]
سمات
مصطلحات
في الوثائق التاريخية، كان مصطلح "حرف" يستخدم غالبًا بدلاً من "بايت" لسلاسل C، مما يدفع العديد [ من؟ ] إلى الاعتقاد بأن هذه الوظائف لا تعمل بطريقة ما مع UTF-8 . في الواقع، يتم تعريف جميع الأطوال على أنها بايتات وهذا صحيح في جميع التنفيذات، وتعمل هذه الوظائف أيضًا مع UTF-8 كما هو الحال مع ترميزات البايت الفردي. تم إصلاح وثائق BSD لتوضيح ذلك، لكن وثائق POSIX وLinux وWindows لا تزال تستخدم "حرف" في العديد من الأماكن حيث يكون "بايت" أو "wchar_t" هو المصطلح الصحيح.
يمكن لوظائف التعامل مع مخازن الذاكرة معالجة تسلسلات من البايتات التي تتضمن بايتًا فارغًا كجزء من البيانات. تبدأ أسماء هذه الوظائف عادةً بـ mem، على عكس strالبادئة.
العناوين
يتم إعلان معظم الوظائف التي تعمل على سلاسل C في string.hالعنوان ( cstringفي C++)، بينما يتم إعلان الوظائف التي تعمل على سلاسل C في wchar.hالعنوان ( cwcharفي C++). تحتوي هذه العناوين أيضًا على إعلانات الوظائف المستخدمة في التعامل مع مخازن الذاكرة؛ وبالتالي فإن الاسم غير دقيق إلى حد ما.
الوظائف المعلنة في string.hتحظى بشعبية كبيرة نظرًا لأنها، كجزء من مكتبة C القياسية ، مضمونة للعمل على أي منصة تدعم C. ومع ذلك، توجد بعض مشكلات الأمان مع هذه الوظائف، مثل تجاوزات المخزن المؤقت المحتملة عند عدم استخدامها بعناية وبشكل صحيح، مما يتسبب في تفضيل المبرمجين للمتغيرات الأكثر أمانًا وربما الأقل قابلية للنقل، والتي تم سرد بعض المتغيرات الشائعة منها أدناه. تنتهك بعض هذه الوظائف أيضًا صحة الثوابت من خلال قبول constمؤشر سلسلة وإرجاع constمؤشر غير موجود داخل السلسلة. لتصحيح هذا، تم فصل بعضها إلى دالتين محملتين في إصدار C++ من المكتبة القياسية.
الثوابت والأنواع
| اسم | ملحوظات |
|---|---|
| باطل | توسيع الماكرو إلى ثابت المؤشر الفارغ ؛ أي ثابت يمثل قيمة مؤشر من المؤكد أنها ليست عنوانًا صالحًا لكائن في الذاكرة. |
| وشار_ت | النوع المستخدم لوحدة التعليمات البرمجية في السلاسل "العريضة". على نظام التشغيل Windows ، المنصة الوحيدة التي تستخدم wchar_t على نطاق واسع، يتم تعريفه على أنه 16 بت [8] وهو ما كان كافيًا لتمثيل أي حرف Unicode ( UCS-2 )، ولكنه الآن يكفي فقط لتمثيل وحدة تعليمات برمجية UTF-16 ، والتي يمكن أن تكون نصف نقطة تعليمات برمجية. على منصات أخرى، يتم تعريفه على أنه 32 بت ونقطة تعليمات برمجية Unicode مناسبة دائمًا. يتطلب معيار C فقط أن يكون wchar_t عريضًا بما يكفي لاحتواء أوسع مجموعة أحرف بين الإعدادات المحلية للنظام المدعومة [9] وأن يكون أكبر أو مساوٍ في الحجم لـ char ، [10] |
| شتا | نوع عدد صحيح يمكنه الاحتفاظ بأي قيمة لـ wchar_t بالإضافة إلى قيمة الماكرو WEOF. لا يتغير هذا النوع عن طريق الترقيات الصحيحة. عادةً ما تكون قيمة موقعة مكونة من 32 بت. |
| char8_t [11] | جزء من معيار C منذ C23، في <uchar.h> ، وهو نوع مناسب لتخزين أحرف UTF-8. [12] |
| char16_t [13] | جزء من معيار C منذ C11 ، [14] في <uchar.h> ، نوع قادر على الاحتفاظ بـ 16 بت حتى لو كان wchar_t بحجم آخر. إذا تم تعريف الماكرو على أنه 1 ، فسيتم استخدام النوع لـ UTF-16 على هذا النظام. هذه هي الحال دائمًا في C23. [15] لا تحدد C++ مثل هذا الماكرو، ولكن يتم استخدام النوع دائمًا لـ UTF-16 في تلك اللغة. [16]__STDC_UTF_16__
|
| char32_t [13] | جزء من معيار C منذ C11، [17] في <uchar.h> ، نوع قادر على الاحتفاظ بـ 32 بت حتى لو كان wchar_t بحجم آخر. إذا تم تعريف الماكرو على أنه 1 ، يتم استخدام النوع لـ UTF-32 على هذا النظام. هذه هي الحال دائمًا في C23. [15] لا تحدد C++ مثل هذا الماكرو، ولكن يتم استخدام النوع دائمًا لـ UTF-32 في تلك اللغة. [16]__STDC_UTF_32__
|
| mbstate_t | يحتوي على كافة المعلومات حول حالة التحويل المطلوبة من استدعاء وظيفة إلى أخرى. |
الوظائف
| سلسلة البايتات |
سلسلة عريضة |
الوصف [ملاحظة 1] | |
|---|---|---|---|
التلاعب بالأوتار |
[18] strcpy | [19] wcscpy | نسخ سلسلة واحدة إلى أخرى |
| [20] strncpy | [21] wcsncpy | يكتب بالضبط n بايت، عن طريق النسخ من المصدر أو إضافة قيم فارغة | |
| [22] strcat | [23] wcscat | إضافة سلسلة إلى أخرى | |
| [24] strncat | [25] wcsncat | لا يضيف أكثر من n بايت من سلسلة إلى أخرى | |
| strxfrm [26] | wcsxfrm [27] | تحويل السلسلة وفقًا للوضع المحلي الحالي | |
فحص الأوتار |
سترلين [28] | ويكسلن [29] | إرجاع طول السلسلة |
| [30] strcmp | [31] wcscmp | مقارنة سلسلتين ( مقارنة ثلاثية ) | |
| [32] strncmp | [33] wcsncmp | مقارنة عدد محدد من البايتات في سلسلتين | |
| ستركول [34] | دبليو سي سكول [35] | مقارنة سلسلتين وفقًا للمكان الحالي | |
| سترتشر [36] | [37] دبليو سي سي إتش آر | يجد أول ظهور للبايت في السلسلة | |
| سترشر [38] | مركز أبحاث الويب [39] | العثور على آخر ظهور للبايت في السلسلة | |
| سترسبن [40] | [41] ويسسبن | إرجاع عدد البايتات الأولية في السلسلة الموجودة في السلسلة الثانية | |
| [42] strcspn | wcscspn [43] | إرجاع عدد البايتات الأولية في السلسلة التي لا توجد في السلسلة الثانية | |
| سترببرك [44] | wcspbrk [45] | يبحث في السلسلة عن أول ظهور لبايت في مجموعة | |
| strstr [46] | wcsstr [47] | يجد أول ظهور لسلسلة فرعية في سلسلة | |
| سترتوك [48] | ويكستوك [49] | تقسيم السلسلة إلى رموز | |
| متنوع | الرعب [50] | — | إرجاع سلسلة تحتوي على رسالة مستمدة من رمز الخطأ |
التلاعب بالذاكرة |
ذاكرة [51] | wmemset [52] | يملأ المخزن المؤقت ببايت متكرر. منذ C23 ، تمت إضافة memset_explicit() لمحو البيانات الحساسة. |
| ميمكبي [53] | wmemcpy [54] | نسخ مخزن مؤقت إلى آخر. منذ C23 ، تمت إضافة memccpy() لربط السلاسل بكفاءة. | |
| ميموف [55] | وميموموف [56] | نسخ مخزن مؤقت إلى مخزن مؤقت آخر، مع إمكانية التداخل مع المخزن المؤقت الآخر | |
| ميمكمب [57] | وميمكمب [58] | مقارنة بين مخزنين مؤقتين (مقارنة ثلاثية الاتجاهات) | |
| ميمشر [59] | وميمشر [60] | يجد أول ظهور للبايت في المخزن المؤقت | |
| |||
وظائف متعددة البايتات
| اسم | وصف |
|---|---|
| مبلن [61] | إرجاع عدد البايتات في الحرف المتعدد البايتات التالي |
| مبتوك [62] | تحويل الحرف المتعدد البايتات التالي إلى حرف عريض |
| قبر [63] | تحويل حرف عريض إلى تمثيله متعدد البايتات |
| مبستووكس [64] | تحويل سلسلة متعددة البايتات إلى سلسلة عريضة |
| مقابر جماعية [65] | تحويل سلسلة عريضة إلى سلسلة متعددة البايتات |
| بتوك [66] | تحويل حرف بايت واحد إلى حرف عريض، إذا كان ذلك ممكنًا |
| وكتوب [67] | تحويل حرف عريض إلى حرف مكون من بايت واحد، إذا كان ذلك ممكنًا |
| مبسنيت [68] | التحقق مما إذا كان كائن الحالة يمثل الحالة الأولية |
| مبيرلين [69] | إرجاع عدد البايتات في الحرف المتعدد البايتات التالي، مع الأخذ في الاعتبار الحالة |
| مبرتوك [70] | يحول الحرف المتعدد البايتات التالي إلى حرف عريض، مع الأخذ في الاعتبار الحالة |
| قبر [71] | يحول حرفًا واسعًا إلى تمثيله متعدد البايتات، مع إعطاء الحالة |
| mbsrtowcs [72] | تحويل سلسلة متعددة البايتات إلى سلسلة عريضة، مع إعطاء الحالة |
| مقابر جماعية [73] | تحويل سلسلة عريضة إلى سلسلة متعددة البايتات، مع إعطاء الحالة |
| مبرتوك8 [74] | يحول الحرف المتعدد البايتات التالي إلى حرف UTF-8، مع إعطاء الحالة |
| القبر [75] | يحول نقطة رمز واحدة من UTF-8 إلى تمثيل أحرف ضيق متعدد البايتات، مع إعطاء الحالة |
| مبرتوك16 [76] | يحول الحرف المتعدد البايتات التالي إلى حرف UTF-16، مع إعطاء الحالة |
| قبر حوالي 16 ق.م [77] | يحول نقطة رمز واحدة من UTF-16 إلى تمثيل أحرف ضيق متعدد البايتات، مع إعطاء الحالة |
| مبرتوك32 [78] | يحول الحرف المتعدد البايتات التالي إلى حرف UTF-32، مع إعطاء الحالة |
| c32rtomb [79] | يحول نقطة رمز واحدة من UTF-32 إلى تمثيل أحرف ضيق متعدد البايتات، مع إعطاء الحالة |
كل هذه الوظائف تحتاج إلىmbstate_tالكائن، الموجود أصلاً في الذاكرة الثابتة (مما يجعل الوظائف غير آمنة للخيوط) وفي الإضافات اللاحقة يجب على المتصل الحفاظ عليه. كان الغرض من هذا في الأصل تتبع حالات التحول فيميجا بايتالترميزات الحديثة مثل UTF-8 لا تحتاج إلى هذا. ومع ذلك، تم تصميم هذه الوظائف على افتراض أنمرحاضالترميز ليس ترميزًا بعرض متغير وبالتالي تم تصميمه للتعامل مع واحد فقطوشار_تفي كل مرة، قم بتمريرها بالقيمة بدلاً من استخدام مؤشر سلسلة. نظرًا لأن UTF-16 عبارة عن ترميز بعرض متغير،mbstate_tتم إعادة استخدامه لتتبع الأزواج البديلة في الترميز الواسع، على الرغم من أن المتصل لا يزال يتعين عليه اكتشاف الاتصالمبتوكمرتين لحرف واحد. [80] [81] [82] تعترف الإضافات اللاحقة للمعيار بأن التحويل الوحيد الذي يهتم به المبرمجون هو بين UTF-8 وUTF-16 ويوفرون ذلك بشكل مباشر.
التحويلات الرقمية
| سلسلة البايتات |
سلسلة عريضة |
الوصف [ملاحظة 1] |
|---|---|---|
| أتوف [83] | — | يحول السلسلة إلى قيمة فاصلة عائمة ('atof' تعني 'ASCII إلى قيمة عائمة') |
| أتو أتول أتول [84] |
— | يحول السلسلة إلى عدد صحيح ( C99 ) ('atoi' تعني 'ASCII إلى عدد صحيح') |
| strtof ( C99 ) [85] strtod [86] strtold ( C99 ) [87] |
wcstof ( C99 ) [88] wcstod [89] wcstold ( C99 ) [90] |
يحول السلسلة إلى قيمة فاصلة عائمة |
| سترتول سترتول [91] |
wcstol wcstoll [92] |
تحويل السلسلة إلى عدد صحيح موقّع |
| سترتول سترتول [93] |
wcstoul wcstoull [94] |
تحويل السلسلة إلى عدد صحيح غير موقّع |
| ||
تحتوي مكتبة C القياسية على العديد من الوظائف للتحويلات الرقمية. الوظائف التي تتعامل مع سلاسل البايتات محددة في header stdlib.h( cstdlibheader في C++). الوظائف التي تتعامل مع سلاسل عريضة محددة في wchar.hheader ( cwcharheader في C++).
الوظائف strchr, bsearch, strpbrk, strrchr, strstr, memchrونظيراتها العريضة ليست ثابتة ، لأنها تقبل constمؤشر سلسلة وتعيد constمؤشرًا غير موجود داخل السلسلة. تم إصلاح هذا في C23 . [95]
كما أنه منذ التعديل المعياري 1 (C95)، atoxxتعتبر الوظائف خاضعة strtoxxxللوظائف، ولهذا السبب لا يوفر C95 ولا أي معيار لاحق إصدارات واسعة النطاق من هذه الوظائف. والحجة ضد ذلك atoxxهي أنها لا تفرق بين الخطأ و 0. [96]
الإضافات الشعبية
| اسم | مصدر | وصف |
|---|---|---|
| بزيرو [97] [98] | بي إس دي | يملأ المخزن المؤقت بصفر بايت، وهو أمر قديم في memset |
| ميمكبي [99] | سفيد | جزء من معيار C منذ C23 ، يقوم بالنسخ بين منطقتي ذاكرة غير متداخلتين، ويتوقف عند العثور على بايت معين. |
| ميمبكبي [100] | جنو | متغير من memcpy يعيد مؤشرًا إلى البايت الذي يلي البايت المكتوب الأخير |
| [101] strcasecmp | بي إس دي | إصدار غير حساس لحالة الأحرف من strcmp |
| strcat_s [102] | نوافذ | متغير من strcat يتحقق من حجم المخزن المؤقت للوجهة قبل النسخ |
| [103] strcpy_s | نوافذ | متغير من strcpy يتحقق من حجم المخزن المؤقت للوجهة قبل النسخ |
| ستردوب وستردوب [104 ] | بوسيكس | جزء من معيار C منذ C23، يخصص سلسلة ويضاعفها |
| سترورر [105] | POSIX 1، جنو | نسخة من strerror آمنة للخيوط. نسخة GNU غير متوافقة مع نسخة POSIX. |
| ستريمب [106] | نوافذ | إصدار غير حساس لحالة الأحرف من strcmp |
| [107] strlcpy | بي إس دي | متغير من strcpy يقوم بتقليص النتيجة لتناسب المخزن المؤقت للوجهة [108] |
| [107] سترلكات | بي إس دي | متغير من strcat يقوم بقص النتيجة لتناسب المخزن المؤقت للوجهة [108] |
| إشارة السلسلة [109] | بوسيكس:2008 | يعيد تمثيل سلسلة من رمز الإشارة . ليس آمنًا للخيوط. |
| [110] strtok_r | بوسيكس | متغير من strtok آمن للخيوط |
البدائل
على الرغم من الحاجة الراسخة لاستبدال strcat[22] و strcpy[18] بوظائف لا تسمح بتجاوزات المخزن المؤقت، لم ينشأ أي معيار مقبول. ويرجع هذا جزئيًا إلى الاعتقاد الخاطئ لدى العديد من مبرمجي C بأن strncatو strncpyلديهما السلوك المطلوب؛ ومع ذلك، لم يتم تصميم أي من الوظيفتين لهذا الغرض (كان المقصود منهما التلاعب بمخازن سلسلة ثابتة الحجم مبطنة بعلامات فارغة، وهو تنسيق بيانات أقل استخدامًا في البرامج الحديثة)، والسلوك والحجج غير بديهية وغالبًا ما تكون مكتوبة بشكل غير صحيح حتى من قبل المبرمجين الخبراء. [108]
البديل الأكثر شيوعًا [a] هو الدالتان strlcat[111] و strlcpy[112] ، اللتان ظهرتا في OpenBSD 2.4 في ديسمبر 1998. [108] تكتب هذه الدالتان دائمًا قيمة NUL واحدة في المخزن المؤقت للوجهة، وتقطع النتيجة إذا لزم الأمر، وتعيد حجم المخزن المؤقت المطلوب، مما يسمح باكتشاف القطع ويوفر حجمًا لإنشاء مخزن مؤقت جديد لن يتم قطعه. لفترة طويلة لم يتم تضمينها في مكتبة GNU C (التي تستخدمها البرامج على Linux)، على أساس كونها غير فعالة، [113] وتشجع على استخدام سلاسل C (بدلاً من بعض أشكال السلاسل البديلة المتفوقة)، [114] [115] وإخفاء أخطاء محتملة أخرى. [116] [117] حتى مع عدم إضافة الدعم لـ glibc، فقد تم تنفيذ strlcat و strlcpy في عدد من مكتبات C الأخرى بما في ذلك تلك الخاصة بـ OpenBSD و FreeBSD و NetBSD و Solaris و OS X و QNX ، وكذلك في مكتبات C البديلة لنظام Linux، مثل libbsd، التي تم تقديمها في عام 2008، [118] و musl ، التي تم تقديمها في عام 2011، [119] [120] وتمت إضافة الكود المصدر مباشرة إلى مشاريع أخرى مثل SDL و GLib و ffmpeg و rsync وحتى داخليًا في نواة Linux . تغير هذا في عام 2024، حيث تشير الأسئلة الشائعة حول glibc إلى أنه اعتبارًا من glibc 2.38، تم تأكيد الكود [121] وبالتالي تمت إضافته. [122] تم توحيد هذه الوظائف كجزء من POSIX.1-2024، [123] تتبع معرف Austin Group Defect Tracker ID 986 بعض المناقشات حول مثل هذه الخطط لـ POSIX.
في بعض الأحيان يتم استخدام memcpy[53] أو memmove[55] ، حيث قد تكون أكثر كفاءة من strcpyعدم التحقق بشكل متكرر من وجود NUL (وهذا أقل صحة في المعالجات الحديثة). نظرًا لأنها تحتاج إلى طول المخزن المؤقت كمعلمة، فإن الضبط الصحيح لهذه المعلمة يمكن أن يتجنب فيضانات المخزن المؤقت.
كجزء من دورة حياة تطوير الأمان لعام 2004 ، قدمت شركة Microsoft عائلة من الوظائف "الآمنة" بما في ذلك strcpy_sو strcat_s(إلى جانب العديد من الوظائف الأخرى). [124] تم توحيد هذه الوظائف مع بعض التغييرات الطفيفة كجزء من C11 الاختياري (الملحق K) المقترح بواسطة ISO/IEC WDTR 24731. [125] تقوم هذه الوظائف بإجراء فحوصات مختلفة بما في ذلك ما إذا كانت السلسلة طويلة جدًا بحيث لا تتناسب مع المخزن المؤقت. إذا فشلت الفحوصات، يتم استدعاء وظيفة "معالج قيود وقت التشغيل" المحددة من قبل المستخدم، [126] والتي عادةً ما تلغي البرنامج. [127] [128] جذبت هذه الوظائف انتقادات كبيرة لأنها في البداية تم تنفيذها فقط على نظام التشغيل Windows وفي نفس الوقت بدأت رسائل التحذير في الظهور بواسطة Microsoft Visual C++ مما يشير إلى استخدام هذه الوظائف بدلاً من الوظائف القياسية. وقد تكهن البعض بأن هذا محاولة من جانب Microsoft لحبس المطورين في منصتها. [129] أظهرت التجربة مع هذه الوظائف مشاكل كبيرة في تبنيها وأخطاء في الاستخدام، لذا تم اقتراح إزالة الملحق K للمراجعة التالية لمعيار C. [130] تم اقتراح استخدام memset_sكطريقة لتجنب تحسينات المترجم غير المرغوب فيها. [131] [132]
انظر أيضا
- بناء جملة لغة C § السلاسل – بناء جملة الكود المصدر، بما في ذلك تسلسلات الإفلات المائلة العكسية
- وظائف السلسلة
- تعبيرات منتظمة متوافقة مع Perl (PCRE)
ملحوظات
- ^ على GitHub، هناك 7,813,206 استخدامًا لـ
strlcpy، مقابل 38,644 استخدامًا لـstrcpy_s(و 15,286,150 استخدامًا لـstrcpy). [ بحاجة لمصدر ]
مراجع
- ^ abc "مسودة المعيار C99 + TC3" (PDF) . §7.1.1p1 . تم الاسترجاع في 7 يناير 2011 .
{{cite web}}:CS1 maint: الموقع ( الرابط ) - ^ "مسودة المعيار C99 + TC3" (PDF) . §6.4.5p7 . تم الاسترجاع في 7 يناير 2011 .
{{cite web}}:CS1 maint: الموقع ( الرابط ) - ^ "مسودة المعيار C99 + TC3" (PDF) . القسم 6.4.5 الحاشية رقم 66. تم الاسترجاع في 7 يناير 2011 .
{{cite web}}:CS1 maint: الموقع ( الرابط ) - ^ "تخفيف المتطلبات على wchar_t لتتوافق مع الممارسات الحالية" (PDF) .
- ^ "الأنواع الأساسية". en.cppreference.com .
- ^ "مسودة المعيار C99 + TC3" (PDF) . §5.1.1.2 مراحل الترجمة ، ص1 . تم الاسترجاع في 23 ديسمبر 2011 .
{{cite web}}:CS1 maint: الموقع ( الرابط ) - ^ "string literals". en.cppreference.com . تم الاسترجاع في 23 ديسمبر 2019 .
- ^ "c++ - ما فائدة wchar_t في البرمجة العامة؟". Stack Overflow . تم الاسترجاع في 1 أغسطس 2022 .
- ^ "stddef.h - تعريفات النوع القياسية". The Open Group . تم الاسترجاع في 28 يناير 2017 .
- ^ جيلام، ريتشارد (2003). Unicode Demystified: A Practical Programmer's Guide to the Encoding Standard. Addison-Wesley Professional. ص. 714. ISBN 9780201700527.
- ^ "char, wchar_t, char8_t, char16_t, char32_t". docs.microsoft.com . تم الاسترجاع في 1 أغسطس 2022 .
- ^ "char8_t".
- ^ من "<cuchar> (uchar.h)".
- ^ "char16_t".
- ^ ab "استبدال وحدات الماكرو النصية".
- ^ ab "الأنواع الأساسية".
- ^ "char32_t".
- ^ ab "strcpy - cppreference.com". En.cppreference.com. 2 يناير 2014. تم الاسترجاع 6 مارس 2014 .
- ^ "wcscpy - cppreference.com". En.cppreference.com . تم الاسترجاع في 6 مارس 2014 .
- ^ "strncpy - cppreference.com". En.cppreference.com. 4 أكتوبر 2013. تم الاسترجاع 6 مارس 2014 .
- ^ "wcsncpy - cppreference.com". En.cppreference.com . تم الاسترجاع في 6 مارس 2014 .
- ^ ab "strcat - cppreference.com". En.cppreference.com. 8 أكتوبر 2013. تم الاسترجاع في 6 مارس 2014 .
- ^ "wcscat - cppreference.com". En.cppreference.com . تم الاسترجاع في 6 مارس 2014 .
- ^ "strncat - cppreference.com". En.cppreference.com. 1 يوليو 2013. تم الاسترجاع في 6 مارس 2014 .
- ^ "wcsncat - cppreference.com". En.cppreference.com . تم الاسترجاع في 6 مارس 2014 .
- ^ "strxfrm - cppreference.com". En.cppreference.com . تم الاسترجاع في 6 مارس 2014 .
- ^ "wcsxfrm - cppreference.com". En.cppreference.com . تم الاسترجاع في 6 مارس 2014 .
- ^ "strlen - cppreference.com". En.cppreference.com. 27 ديسمبر 2013. تم الاسترجاع في 6 مارس 2014 .
- ^ "wcslen - cppreference.com". En.cppreference.com . تم الاسترجاع في 6 مارس 2014 .
- ^ "strcmp - cppreference.com". En.cppreference.com . تم الاسترجاع في 6 مارس 2014 .
- ^ "wcscmp - cppreference.com". En.cppreference.com . تم الاسترجاع في 6 مارس 2014 .
- ^ "strncmp - cppreference.com". En.cppreference.com . تم الاسترجاع في 6 مارس 2014 .
- ^ "wcsncmp - cppreference.com". En.cppreference.com . تم الاسترجاع في 6 مارس 2014 .
- ^ "strcoll - cppreference.com". En.cppreference.com . تم الاسترجاع في 6 مارس 2014 .
- ^ "wcscoll - cppreference.com". En.cppreference.com . تم الاسترجاع في 6 مارس 2014 .
- ^ "strchr - cppreference.com". En.cppreference.com. 23 فبراير 2014. تم الاسترجاع 6 مارس 2014 .
- ^ "wcschr - cppreference.com". En.cppreference.com . تم الاسترجاع في 6 مارس 2014 .
- ^ "strrchr - cppreference.com". En.cppreference.com . تم الاسترجاع في 6 مارس 2014 .
- ^ "wcsrchr - cppreference.com". En.cppreference.com . تم الاسترجاع في 6 مارس 2014 .
- ^ "strspn - cppreference.com". En.cppreference.com . تم الاسترجاع في 6 مارس 2014 .
- ^ "wcsspn - cppreference.com". En.cppreference.com . تم الاسترجاع في 6 مارس 2014 .
- ^ "strcspn - cppreference.com". En.cppreference.com. 31 مايو 2013. تم الاسترجاع في 6 مارس 2014 .
- ^ "wcscspn - cppreference.com". En.cppreference.com . تم الاسترجاع في 6 مارس 2014 .
- ^ "strpbrk - cppreference.com". En.cppreference.com. 31 مايو 2013. تم الاسترجاع في 6 مارس 2014 .
- ^ "wcspbrk - cppreference.com". En.cppreference.com . تم الاسترجاع في 6 مارس 2014 .
- ^ "strstr - cppreference.com". En.cppreference.com. 16 أكتوبر 2013. تم الاسترجاع في 6 مارس 2014 .
- ^ "wcsstr - cppreference.com". En.cppreference.com . تم الاسترجاع في 6 مارس 2014 .
- ^ "strtok - cppreference.com". En.cppreference.com. 3 سبتمبر 2013. تم الاسترجاع 6 مارس 2014 .
- ^ "wcstok - cppreference.com". En.cppreference.com . تم الاسترجاع في 6 مارس 2014 .
- ^ "strerror - cppreference.com". En.cppreference.com. 31 مايو 2013. تم الاسترجاع في 6 مارس 2014 .
- ^ "memset - cppreference.com". En.cppreference.com . تم الاسترجاع في 6 مارس 2014 .
- ^ "wmemset - cppreference.com". En.cppreference.com . تم الاسترجاع في 6 مارس 2014 .
- ^ ab "memcpy - cppreference.com". En.cppreference.com . تم الاسترجاع في 6 مارس 2014 .
- ^ "wmemcpy - cppreference.com". En.cppreference.com . تم الاسترجاع في 6 مارس 2014 .
- ^ ab "memmove - cppreference.com". En.cppreference.com. 25 يناير 2014. تم الاسترجاع 6 مارس 2014 .
- ^ "wmemmove - cppreference.com". En.cppreference.com . تم الاسترجاع في 6 مارس 2014 .
- ^ "memcmp - cppreference.com". En.cppreference.com . تم الاسترجاع في 6 مارس 2014 .
- ^ "wmemcmp - cppreference.com". En.cppreference.com . تم الاسترجاع في 6 مارس 2014 .
- ^ "memchr - cppreference.com". En.cppreference.com . تم الاسترجاع في 6 مارس 2014 .
- ^ "wmemchr - cppreference.com". En.cppreference.com . تم الاسترجاع في 6 مارس 2014 .
- ^ "mblen - cppreference.com". En.cppreference.com . تم الاسترجاع في 6 مارس 2014 .
- ^ "mbtowc - cppreference.com". En.cppreference.com . تم الاسترجاع في 6 مارس 2014 .
- ^ "wctomb - cppreference.com". En.cppreference.com. 4 فبراير 2014. تم الاسترجاع 6 مارس 2014 .
- ^ "mbstowcs - cppreference.com". En.cppreference.com . تم الاسترجاع في 6 مارس 2014 .
- ^ "wcstombs - cppreference.com". En.cppreference.com . تم الاسترجاع في 6 مارس 2014 .
- ^ "btowc - cppreference.com". En.cppreference.com . تم الاسترجاع في 6 مارس 2014 .
- ^ "wctob - cppreference.com". En.cppreference.com . تم الاسترجاع في 6 مارس 2014 .
- ^ "mbsinit - cppreference.com". En.cppreference.com . تم الاسترجاع في 6 مارس 2014 .
- ^ "mbrlen - cppreference.com". En.cppreference.com . تم الاسترجاع في 6 مارس 2014 .
- ^ "mbrtowc - cppreference.com". En.cppreference.com . تم الاسترجاع في 6 مارس 2014 .
- ^ "wcrtomb - cppreference.com". En.cppreference.com . تم الاسترجاع في 6 مارس 2014 .
- ^ "mbsrtowcs - cppreference.com". En.cppreference.com . تم الاسترجاع في 6 مارس 2014 .
- ^ "wcsrtombs - cppreference.com". En.cppreference.com . تم الاسترجاع في 6 مارس 2014 .
- ^ "mbrtoc8 – cppreference.com". En.cppreference.com.
- ^ "c8rtomb - cppreference.com".
- ^ "mbrtoc16 - cppreference.com". En.cppreference.com.
- ^ "c16rtomb - cppreference.com". En.cppreference.com.
- ^ "mbrtoc32 - cppreference.com". En.cppreference.com.
- ^ "c23rtomb – cppreference.com". En.cppreference.com.
- ^ "6.3.2 تمثيل حالة التحويل". مكتبة جنو سي . تم الاسترجاع في 31 يناير 2017 .
- ^ "root/src/multibyte/c16rtomb.c" . تم الاسترجاع في 31 يناير 2017 .
- ^ "محتويات /stable/11/lib/libc/locale/c16rtomb.c" . تم الاسترجاع في 31 يناير 2017 .
- ^ "atof - cppreference.com". En.cppreference.com. 31 مايو 2013. تم الاسترجاع 6 مارس 2014 .
- ^ "atoi, atol, atoll - cppreference.com". En.cppreference.com. 18 يناير 2014 . تم الاسترجاع 6 مارس 2014 .
- ^ "strtof, strtod, strtold - cppreference.com". En.cppreference.com. 4 فبراير 2014. تم الاسترجاع في 6 مارس 2014 .
- ^ "strtof, strtod, strtold - cppreference.com". En.cppreference.com. 4 فبراير 2014. تم الاسترجاع في 6 مارس 2014 .
- ^ "strtof, strtod, strtold - cppreference.com". En.cppreference.com. 4 فبراير 2014. تم الاسترجاع في 6 مارس 2014 .
- ^ "wcstof, wcstod, wcstold - cppreference.com". En.cppreference.com . تم الاسترجاع في 6 مارس 2014 .
- ^ "wcstof, wcstod, wcstold - cppreference.com". En.cppreference.com . تم الاسترجاع في 6 مارس 2014 .
- ^ "wcstof, wcstod, wcstold - cppreference.com". En.cppreference.com . تم الاسترجاع في 6 مارس 2014 .
- ^ "strtol, strtoll - cppreference.com". En.cppreference.com. 4 فبراير 2014. تم الاسترجاع 6 مارس 2014 .
- ^ "wcstol, wcstoll - cppreference.com". En.cppreference.com . تم الاسترجاع في 6 مارس 2014 .
- ^ "strtoul, strtoull - cppreference.com". En.cppreference.com. 4 فبراير 2014. تم الاسترجاع 6 مارس 2014 .
- ^ "wcstoul, wcstoull - cppreference.com". En.cppreference.com . تم الاسترجاع في 6 مارس 2014 .
- ^ "WG14-N3020 : وظائف المكتبة القياسية للحفاظ على المؤهل، الإصدار 4" (PDF) . open-std.org . 13 يونيو 2022.
- ^ C99 الأساس المنطقي، 7.20.1.1
- ^ "bzero". المجموعة المفتوحة . تم الاسترجاع في 27 نوفمبر 2017 .
- ^ "bzero(3)". OpenBSD . تم الاسترجاع في 27 نوفمبر 2017 .
- ^ "memccpy". Pubs.opengroup.org . تم الاسترجاع في 6 مارس 2014 .
- ^ "mempcpy(3) - صفحة دليل Linux". Kernel.org . تم الاسترجاع في 6 مارس 2014 .
- ^ "strcasecmp(3) - صفحة دليل Linux". Kernel.org . تم الاسترجاع في 6 مارس 2014 .
- ^ "strcat_s, wcscat_s, _mbscat_s". docs.microsoft.com . تم الاسترجاع في 22 أبريل 2022 .
- ^ "strcpy_s, wcscpy_s, _mbscpy_s, _mbscpy_s_l". docs.microsoft.com . تم الاسترجاع في 22 أبريل 2022 .
- ^ "strdup". Pubs.opengroup.org . تم الاسترجاع في 6 مارس 2014 .
- ^ "strerror(3) - صفحة دليل Linux". man7.org . تم الاسترجاع في 3 نوفمبر 2019 .
- ^ "String | stricmp()". C Programming Expert.com . تم الاسترجاع في 6 مارس 2014 .
- ^ ab "strlcpy, strlcat — نسخ وتسلسل سلاسل محدودة الحجم". OpenBSD . تم الاسترجاع في 26 مايو 2016 .
- ^ abcd Todd C. Miller؛ Theo de Raadt (1999). "strlcpy و strlcat – نسخ وتسلسل متسق وآمن للسلاسل". USENIX '99.
- ^ "strsignal". Pubs.opengroup.org . تم الاسترجاع في 6 مارس 2014 .
- ^ "سترتوك". Pubs.opengroup.org . تم الاسترجاع 6 مارس 2014 .
- ^ تود سي ميلر. "strlcpy.c". مرجع متقاطع لـ BSD .
- ^ تود سي ميلر. "strlcat.c". مرجع متقاطع لـ BSD .
- ^ ميلر، داميان (أكتوبر 2005). "Secure Portability" (PDF) . تم استرجاعه في 26 يونيو 2016. تم اعتماد واجهة برمجة التطبيقات هذه [strlcpy و strlcat] بواسطة معظم أنظمة التشغيل الحديثة والعديد من حزم البرامج المستقلة [...] .
الاستثناء الملحوظ هو مكتبة GNU القياسية C، glibc، التي يرفض صيانتها بشدة تضمين واجهات برمجة التطبيقات المحسنة هذه، ووصفها بأنها "هراء BSD غير فعال بشكل رهيب"، على الرغم من الأدلة السابقة على أنها أسرع في معظم الحالات من واجهات برمجة التطبيقات التي تحل محلها.
- ^ قائمة بريدية libc-alpha مؤرشفة في 9 يونيو 2007 على موقع Wayback Machine ، رسائل مختارة من 8 أغسطس 2000 الموضوع: 53، 60، 61
- ^ الصعود والهبوط في strlcpy(); LWN.net
- ^ "إضافة strlcpy() إلى glibc". lwn.net .
تعني معالجة السلسلة الصحيحة أنك تعرف دائمًا طول سلاسلك وبالتالي يمكنك استخدام memcpy (بدلاً من strcpy).
- ^ – دليل وظائف مكتبة Linux "ومع ذلك، قد يتساءل المرء عن مدى صحة مثل هذه التحسينات، لأنها تتعارض مع الغرض الكامل من strlcpy() و strlcat(). في الواقع، كانت النسخة الأولى من صفحة هذا الدليل خاطئة."
- ^ "libbsd" . تم الاسترجاع في 21 نوفمبر 2022 .
- ^ "root/src/string/strlcpy.c" . تم الاسترجاع في 28 يناير 2017 .
- ^ "root/src/string/strlcat.c" . تم الاسترجاع في 28 يناير 2017 .
- ^ strlc{py|at} الالتزام
- ^ https://news.ycombinator.com/item?id=36765747 [ URL ]
- ^ "strlcat". Pubs.opengroup.org . تم الاسترجاع في 5 سبتمبر 2024 .
- ^ لوفيل، مارتين. "صد الهجمات على الكود الخاص بك باستخدام مكتبات C وC++ الآمنة في Visual Studio 2005" . تم الاسترجاع في 13 فبراير 2015 .
- ^ مكتبة Safe C. "توفر مكتبة Safe C التحقق من الذاكرة ووظائف السلسلة وفقًا لمعيار ISO/IEC TR24731". Sourceforge . تم الاسترجاع في 6 مارس 2013 .
- ^ "مسودة المعيار C11" (PDF) . §K.3.1.4p2 . تم الاسترجاع في 13 فبراير 2013 .
{{cite web}}:CS1 maint: الموقع ( الرابط ) - ^ "مسودة المعيار C11" (PDF) . §K.3.6.1.1p4 . تم الاسترجاع في 13 فبراير 2013 .
{{cite web}}:CS1 maint: الموقع ( الرابط ) - ^ "التحقق من صحة المعلمات". 21 أكتوبر 2022.
- ^ داني كاليف. "إنهم يفعلون ذلك مرة أخرى". InformIT. مؤرشف من الأصل في 15 يناير 2012. تم الاسترجاع في 10 نوفمبر 2011 .
- ^ "الخبرة الميدانية مع الملحق K — واجهات التحقق من الحدود" . تم الاسترجاع في 5 نوفمبر 2015 .
- ^ "MSC06-C. احذر من تحسينات المترجم". SEI CERT C Coding Standard .
- ^ – دليل وظائف مكتبة FreeBSD
روابط خارجية
- Memcpy سريع في C، أمثلة متعددة لترميز C لاستهداف أنواع مختلفة من بنيات تعليمات وحدة المعالجة المركزية
