النصوص في لغة سي
النصوص ( Strings ) و التعامل معها في لغة سي, في درسنا هذا سوف يكون موضوعنا عن التعامل مع النصوص أو ما يُسمََّى بـ Strings. فهل تسائلت كيف بإمكاننا تخزين جُمَل كاملة أو عبارات كإسم شخص أو نص معين, فحسب ما ذكرناه من أنواع البيانات. لا يوجد نوع يمكََّننا من تخزين نص كامل فيه, لكن اقرب هذه الأنواع لذلك هو char الذي يُمكنه تخزين فقط حرف واحد أو رمز واحد.
لنتذكر درسنا السابق الذي تحدثنا به عن المصفوفات, سوف نتخيل النصوص على أنها مصفوفات من نوع char. فبهذه الطريقة يمكننا تخزين مجموعه من الرموز و التعامل معها على أنها قطعه واحدة.
char string[]={'p', 'r', 'o', 'g', 'r', 'a', 'm', 'm', 'e', 'r'};
هذا هو فعليّاً مبدأ النصوص strings في لغة سي فهي عبارة عن مصفوفات من نوع كاركتر char و لكن بدلاً من تخزين النص بالطريقة. المتعبه كما في المثال السابق في تحديد قيم المصفوفات. توجد في لغة سي طريقة أسهل و هي مخصصة لتخزين النصوص فقط و تتم. بوضع النص بين علامتي تنصيص مزدوجة فهاتين الجملتين في لغة سي لهما نفس النتيجة
char string[]={"nusur"};
لكن هنا لا زالت هناك مشكلة و هي أننا لا نستطيع تعديل النص الموجود في هذه المصفوفة. سوى بتعديل كل قيمة على حدى فإن أردنا تخزين جملة tech فعلينا كتابتها بالشكل
char string[]="nusur"; string[0] = 't'; string[1] = 'e'; string[2] = 'c'; string[3] = 'h';
إذ أن لغة سي لا تسمح لنا بإعادة تعيين نص كامل للمصفوفة, و مشكلة أُخرى هي أنه عند تعريفنا للمصفوفة. قُمنا بتحديد سعتها و لا يمكن تغييرها لذا لا يمكن إعادة تحديد قيم المصفوفة. بحيث تحتوي على نص اكبر من ما كان موجوداً. الحل هو أننا سوف نقوم بإستباق بعض الدروس و اللجوء بما يسمى بالمؤشرات pointers و هي عبارة عن وسيلة شبيهة. إلى حد ما للمصفوفات من حيث طريقة حجز الذاكرة.
سوف نتعرف عليها لآحقاً, الآن كل ما علينا أن نعرفه هو أن المؤشرات يرمز إليها بإشارة النجمة لذلك بدلاً من تعريف النص كمصفوفة. نقوم بتعريفه كمؤشر عن طريق وضع نجمة قبل إسم المتغير, اصبحت عملية تعريف النص و إعادة تعيينه سهلة جداً.
char *string = "nusur"; string = "tech";
لنقُم بكتابة كود بسيط نقوم فيه بتعريف نص بسيط و طباعته
#include <stdio.h> #include <stdlib.h> int main(int argc, char** argv) { char *str = "I am Programmer and Designer \n"; printf("%s", str); return 0; }
لقد قُمنا بتعريق نص و كتبنا به أنا مبرمج و مصمم باللغة الإنجليزية و عرَّفناه char على أنهُ مؤشر و وضعنا str إختصاراً لـ string. ثم خزنّنا النص به, ثم طبعنا هذا النص على الشاشة و كتبنا %s أي إختصاراً أنه نريد طباعة. نص من نوع نص و وضعنا str بعد الفاصلة و عند تشغيل الكود سوف يقوم بطباعة الجملة لنا كما بالشكل
I am Programmer and Designer
بدلا من كتابة كامل النص عند دالة الطباعة printf قمنا بتخزينه في متغير إسمه str و سهّل علينا الكتابة داخل دالة printf.
العمليات على النصوص في لغة C
سنقوم بالتعرُّف على بعض العمليات التي بإمكاننا إجرائها على النصوص, على سبيل المثال.
- كيف لنا أن نقارن بين نص و نص آخر؟
- هل نستخدم اشارة المساواة == كما فعلنا مع الأعداد بالدروس السابقة؟
- كيف يمكننا دمج نصين مع بعضهما البعض؟
- كيف لنا أن نعرف عدد الأحرف في نص معين؟
كل هذه التسائُلات سوف نجيب عنها بعد قليل.
توفّر لنا لغة سي بعض الدوال التي يُمكننا الإستفادة منها لإجراء العمليات المختلفة على النصوص, و لكي. نستطيع إستخدام هذه الدوال علينا إدراج الملف الذي يحتوي على تعريف هذه الدوال و ذلك بكتابة.
#include <string.h>
في أعلى الملف المصدري ببداية الكود فهذه الجملة تُخبِر المحوِّل البرمجي بأننا نُريد إدراج الملف. المسمى string.h في ملفنا المصدري. و من الجدير بالذكر يتم تثبيته بشكل تلقائي على جهاز الكمبيوتر عند تثبيت أي محول برمجي للغة سي, و هذا الملف. يحتوي على تعريف جميع الدوال المخصصة بالنصوص. بعد إدراج الملف string.h أصبَح الآن بإمكاننا الإستفادة من الدوال التي يحتويها.
دالة strcmp للمقارنة بين نصين في لغة سي
دالة strcmp هي دالة متخصصة بمقارنة نصين, أي مصفوفتين من نوع char و تُسمى هذه الدالة بـ strcmp أي مقارنة النصوص. و تقوم هذه الدالة بأخذ نصين كمعاملات و المقارنة بينهما و تقوم بإرجاع عدد صحيح و هذا العدد الصحيح يمثِّل ما. إذا كان النصان متساويان أم لا. ففي حال كان النصان متساويان فسيكون الناتج. لهذه الدالة هو العدد 0 عدا عن ذلك سيتم إرجاع قيمة. أُخرى غير العدد 0.
قد تتسائل لماذا نلجأ لإستخدام دالة بدلاً من مجرد إستخدام إشارتي == كما فعلنا سابقاً؟ هذه الطريقة لن تنفع لمقارنة نصين ابداً و لا حتى في مقارنة أي مصفوفتين و سنعرف. السبب عند الوصول الى درس المؤشرات.
#include <stdio.h> #include <stdlib.h> #include <string.h> int main(int argc, char** argv) { char *cs1, *cs2; cs1 = "nusurtech.ca"; cs2 = "www.nusurtech.ca"; int x = strlen(cs1); printf("%d", x); int status = strcmp(cs1, cs2); if(status == 0) { printf("The two texts are equal %d", x); } else{ printf("The two texts are not equal"); } return 0; }
في البداية قُمنا بإستدعاء المكتبة الخاصة بالتعامل مع النصوص string.h. و قُمنا بتعريف نصين على أنهم char و النصين هما cs1 للنص الأول و cs2 للنص الثاني و عرَّفنا متغير status لوضع ناتج المقارنة به. و كتبنا الدالة strcmp و إخترنا له قارن لنا بين cs1 و cs2 و كتبنا له شرط ما إن كانت status تساوي 0 أي أن النصان متساويان. إطبع لنا طول النص و إذا كان غير ذلك إطبع لنا أنهما غير متساويان و عند تشغيل البرنامج.
19The two texts are equal 19
عندما يكون النصان غير متساويان
19The two texts are not equal
دالة strlen لمعرفة طول النص في لغة C
دالة strlen هي دالة تُستخدَم لمعرفة طول النص و تأخذ فقط مُعامل واحد و هو نص و تقوم بإرجاع عدد الأحرف في هذا النص كعدد صحيح.
#include <stdio.h> #include <stdlib.h> #include <string.h> int main(int argc, char** argv) { char *cs1, *cs2; cs1 = "www.nusurtech.ca"; cs2 = "www.nusurtech.ca"; int x = strlen(cs1); printf("%d", x); return 0; }
في البداية قُمنا بإستدعاء المكتبة الخاصة بالتعامل مع النصوص string.h و قُمنا بتعريف نصين. على أنهم char و النصين هما cs1 للنص الأول و cs2 للنص الثاني. و عرَّفنا متغيرين وضعنا بهم النصوص, و وضعنا الناتج في مُتغير عددي و هو x و كتبنا الدالة strlen و كتبنا إسم المُتغير cs1 من. أجل حساب طوله, و طبعنا الناتج عبر printf و عند تشغيل البرنامج تكون نتيجته هي
19
دالة strcat لدمج النصوص مع بعضها في C
دالة strcat هي دالة تُستخدم لدمج نصين مع بعضهما البعض عن طريق نقل النص source إلى نهاية النص. destination و يجب أن تكون المصفوفة destination كبيرة كفاية لإحتواء ناتج دمج النصين
#include <stdio.h> #include <stdlib.h> #include <string.h> int main(int argc, char** argv) { char *cs = "=tech"; char saja[15] = "nusur"; strcat(saja, cs); printf("My website = %s \n", saja); return 0; }
في البداية قٌمنا بإنشاء نصان الأول هو cs من نوع char pointer و النص هو -tech و النص الثاني هو saja كان مصفوفة من char. و تحتوي على كلمة programmer لكي يتم دمجهم مع بعضهما البعض ووضعنا رقم 15 أي هو طول المصفوفة. النصين طولهم 15 و طولهم الأصلي هو 14 وضعنا رقم زيادة و السبب هو في لغة سي لا يمكن أن نعرف. متى ينتهي. إلا من خلال رمز خاص يسمى السبب هو في لغة سي لا يمكن أن نعرف متى ينتهي إلا من خلال رمز خاص يسمى null terminator و يرمز له بـ /0.
يتم إضافة هذا الرمز الخاص في نهاية النص و هذا الرمز يحتاج إلى مكان خاص به يتسعه في الذاكرة هو يضاف بشكل تلقائي عند إضافه نصوص Strings جديدة أو إستخدام احدى دوال التعامل مع النصوص. لكن كل ما علينا أن نجعل له مكان في الذاكرة ليتسعه لذلك ننصح دائماً أن نقوم باضافه 1 إلى سعة مصفوفة النص عند تحديدها بشكل يدوي لتفادي أي مشكلة تحدث. و من ثم كتبنا الدالة strcat و إخترنا له النصين لكي يتم دمجهم, و قُمنا بإستخدام دالة الطباعة و كتبنا له My website. ثم يطبع لنا بعدها saja لأن النص تم تخزينه في saja و عند تشغيل البرنامج سنحصل على النتيجة التالية
My website = nusur tech