سلاسل النصوص في C: كيفية تعريف Strings في لغة البرمجة C
مقدمة إلى Strings في لغة C
تتعامل الحواسيب مع أنواع متعددة من البيانات، وتُعد النصوص أو Strings واحدة من أكثرها استخدامًا في التطبيقات البرمجية. لكن التعامل مع السلاسل النصية في لغة C يختلف عن كثير من اللغات الحديثة، لأن C لا توفر نوع بيانات مدمجًا باسم string. لذلك، يعتمد تخزين النصوص في C على مفهوم مصفوفات المحارف أو char arrays.
في هذا المقال، سنشرح بطريقة عملية واحترافية كيفية تعريف السلاسل النصية في C، مع توضيح العلاقة بين data types وvariables وarrays، حتى تتكون لديك صورة واضحة عن آلية عمل Strings داخل الذاكرة.

أنواع البيانات الأساسية في C
تحتوي لغة C على مجموعة من أنواع البيانات المدمجة، من أشهرها:
intshortlongfloatdoublelong doublechar
الملاحظة المهمة هنا هي عدم وجود نوع مخصص باسم string، وهذا يعني أن النصوص لا تُخزَّن في C بالطريقة المعتادة الموجودة في لغات أخرى مثل JavaScript أو Python.
نوع البيانات char ودوره في تمثيل المحارف
النوع char هو الوسيلة الأساسية لتمثيل محرف واحد فقط في C. ويمكن أن يكون هذا المحرف حرفًا، أو رقمًا، أو رمزًا، أو حتى مسافة فارغة. وغالبًا ما يُمثل وفق جدول ASCII.
يجب كتابة المحرف المفرد بين علامتي اقتباس مفردتين:
'D', '!', '5', 'l', ' '
كل قيمة من القيم السابقة تُعد char صالحًا، لأنها تحتوي على محرف واحد فقط.
أما إذا كتبت عدة محارف داخل اقتباس مفرد، فلن يكون ذلك صحيحًا:
'freeCodeCamp is awesome'
السبب هو أن char لا يقبل إلا محرفًا واحدًا. وعندما نريد التعبير عن مجموعة من المحارف المتتالية، فإننا نستخدم String literal داخل علامات اقتباس مزدوجة:
"freeCodeCamp is awesome"
كيفية تعريف المتغيرات في C
لتخزين أي قيمة في C، نستخدم المتغيرات. ويمكنك تصور المتغير على أنه مساحة محفوظة في الذاكرة لتخزين قيمة قابلة للاستخدام لاحقًا داخل البرنامج.
لغة C هي لغة statically typed، أي يجب تحديد نوع البيانات عند إنشاء المتغير. والصيغة العامة تكون كالتالي:
#include <stdio.h>
int main(void) {
char letter = 'D';
// creates a variable named letter
// it holds only values of type char
// the single character 'D' is assigned to letter
}
من المهم جدًا عدم الخلط بين أنواع البيانات. فمثلًا، إذا استخدمت علامات اقتباس مزدوجة مع متغير من نوع char، فسيؤدي ذلك إلى خطأ أو تحذير أثناء الترجمة:
#include <stdio.h>
int main(void) {
char letter = "D";
// output:
// warning: incompatible pointer to integer conversion initializing 'char' with an expression of type 'char [2]'
}
وهنا يتضح أن C لا تدعم متغيرات نصية مباشرة، بل تعتمد على أسلوب آخر لتخزين النصوص.
ما هي Arrays في لغة C؟
الـ array هي بنية تخزينية تسمح لك بحفظ عدة قيم من نفس النوع داخل متغير واحد. وهذا يعني أنه يمكنك إنشاء مصفوفة للأعداد الصحيحة أو للأعداد العشرية أو للمحارف، ولكن لا يمكنك خلط الأنواع داخل المصفوفة نفسها.
مثال على تعريف مصفوفة من النوع int:
int numbers[3];
في هذا المثال:
intهو نوع البيانات.numbersهو اسم المصفوفة.[3]تعني أن المصفوفة تتسع لثلاث قيم.
بعد تعريف المصفوفة، يمكنك إسناد القيم باستخدام الفهارس indexing، والتي تبدأ من 0:
// Define the array; it can hold 3 values
int numbers[3];
// assign values
numbers[0] = 1;
numbers[1] = 2;
numbers[2] = 3;
وللوصول إلى عنصر معين:
numbers[2]; // returns 3
ما العلاقة بين Arrays وStrings في C؟
هنا نصل إلى الفكرة الأساسية: السلاسل النصية في C هي في الحقيقة مصفوفات من المحارف. أي أن String ليس نوعًا مستقلًا، بل هو char array يحتوي على سلسلة من القيم من النوع char.
بمعنى آخر، كل نص في C هو مجموعة محارف متجاورة مخزنة في الذاكرة.
كيف تعمل Strings في C؟
كل String في لغة C يجب أن ينتهي بمحرف خاص يسمى string terminator أو null terminator، ويُكتب بهذه الصورة:
'\0'
هذا المحرف يخبر اللغة أن النص انتهى عند هذا الموضع. ومن المهم عدم الخلط بينه وبين:
- الرقم
0 - المحرف
'0'
فـ '\0' يختلف عنهما تمامًا، لأنه قيمة خاصة تُستخدم لإنهاء السلسلة النصية.
تُضاف هذه النهاية تلقائيًا عند إنشاء النصوص في C، لكنها لا تظهر لك بشكل مباشر أثناء الطباعة أو المعالجة.

على سبيل المثال، النص "hello" يتكون من 5 أحرف، لكنه يحتاج إلى 6 bytes في الذاكرة، لأن هناك byte إضافيًا مخصصًا لـ '\0'.
طول السلسلة النصية في C
طول الـ String هو عدد المحارف الفعلية فقط، من دون احتساب null terminator.
على سبيل المثال:
"freeCodeCamp"طوله 12 محرفًا."I code"طوله 6 محارف، لأن المسافة تُحسب ضمن الطول.
لذلك، يجب التفريق بين:
- طول النص: عدد المحارف الظاهرة.
- المساحة المحجوزة في الذاكرة: عدد المحارف + محرف الإنهاء
'\0'.
كيفية تعريف Strings في C باستخدام char array
تعريف مصفوفة محارف فارغة
لبناء String في C، تبدأ باستخدام النوع char ثم اسم المصفوفة، ثم تحدد حجمها داخل الأقواس المربعة:
char city[7];
هذا يعني أن المصفوفة city تستطيع تخزين 7 محارف كحد أقصى، بما في ذلك '\0'.
تهيئة النص محرفًا محرفًا
يمكنك ملء المصفوفة يدويًا كما يلي:
#include <stdio.h>
int main(void) {
char city[7];
city[0] = 'A';
city[1] = 't';
city[2] = 'h';
city[3] = 'e';
city[4] = 'n';
city[5] = 's';
city[6] = '\0'; // don't forget this!
printf("I live in %s", city);
}
هذه الطريقة صحيحة، لكنها مرهقة وغير عملية في معظم الحالات.
تهيئة String مباشرة عند التعريف
الطريقة الأسهل والأكثر شيوعًا هي تمرير النص مباشرة داخل علامات اقتباس مزدوجة:
#include <stdio.h>
int main(void) {
char city[7] = "Athens";
// defines a character array named city
// it can hold a string up to 7 characters including the string terminator
printf("I live in %s", city);
}
في هذا المثال، الكلمة "Athens" تحتوي على 6 أحرف، ويُضاف إليها '\0' تلقائيًا، لذلك نحتاج إلى 7 خانات.
ترك المترجم يحدد الحجم تلقائيًا
إذا كنت تعرف القيمة منذ البداية، يمكنك ترك المترجم يحسب الحجم المناسب:
char city[] = "Athens";
// equivalent to:
// char city[7] = "Athens";
هذه الطريقة مفيدة عندما لا تحتاج إلى تحديد السعة يدويًا.
حجز مساحة أكبر للتعديل لاحقًا
إذا كنت تخطط لتغيير النص مستقبلاً، فمن الأفضل حجز مساحة أكبر:
char city[15] = "Athens";
هنا تستطيع المصفوفة الاحتفاظ بنص يصل إلى 15 محرفًا، بما في ذلك null terminator. وهذا يمنحك مرونة أكبر عند استبدال القيمة لاحقًا.
كيفية تعديل محتوى String في C
بعد تعريف مصفوفة المحارف، لا يمكنك ببساطة إعادة إسناد قيمة جديدة باستخدام العامل = كما تفعل مع الأنواع البسيطة. لذلك، تعديل String يتطلب أحد حلّين.
الطريقة الأولى: تعديل كل محرف على حدة
#include <stdio.h>
int main(void) {
char city[7] = "Athens";
printf("I live in %s", city);
city[0] = 'L';
city[1] = 'o';
city[2] = 'n';
city[3] = 'd';
city[4] = 'o';
city[5] = 'n';
city[6] = '\0';
printf("\nBut now I live in %s", city);
}
الناتج:
I live in Athens
But now I live in London
رغم أن هذه الطريقة تعمل، فإنها غير مفضلة بسبب كثرة الخطوات وسهولة الوقوع في الأخطاء.
الطريقة الثانية: استخدام الدالة strcpy()
الحل العملي الأفضل هو استخدام الدالة strcpy() الموجودة في المكتبة <string.h>. هذه الدالة تنسخ النص الجديد إلى مصفوفة المحارف، وتضيف '\0' تلقائيًا.
#include <stdio.h>
#include <string.h>
int main(void) {
char city[15] = "Athens";
strcpy(city, "Barcelona");
printf("I am going on holiday to %s", city);
}
الناتج:
I am going on holiday to Barcelona
لكن انتبه إلى نقطة مهمة: يجب أن تكون المصفوفة كبيرة بما يكفي لاستيعاب النص الجديد مع null terminator، وإلا قد يحدث buffer overflow ويتسبب ذلك في مشاكل خطيرة داخل البرنامج.
أفضل الممارسات عند التعامل مع Strings في C
- احجز دائمًا مساحة إضافية من أجل
'\0'. - لا تستخدم
charلتخزين نص كامل، بل لمُحرف واحد فقط. - إذا كنت ستعدّل النص لاحقًا، فحدّد حجمًا أكبر من القيمة الحالية.
- استخدم
strcpy()بحذر، وتأكد من كفاية حجم المصفوفة. - تذكّر أن المسافات تُحتسب ضمن طول النص.
ملخص سريع
| المفهوم | الشرح |
|---|---|
char |
يمثل محرفًا واحدًا فقط |
| String في C | مصفوفة من المحارف char array |
'\0' |
محرف إنهاء السلسلة النصية |
| طول النص | عدد المحارف بدون '\0' |
| المساحة المطلوبة | عدد المحارف + 1 من أجل '\0' |
الخلاصة التقنية
فهم طريقة عمل Strings in C يُعد خطوة أساسية لكل من يريد إتقان هذه اللغة على مستوى أعمق. فرغم أن C لا تقدم نوعًا نصيًا مدمجًا، فإن اعتمادها على char arrays يمنح المبرمج تحكمًا مباشرًا بالذاكرة وبنية البيانات. هذا الأسلوب قوي ومرن، لكنه يتطلب دقة عالية، خصوصًا عند حساب حجم المصفوفة والتعامل مع null terminator. إذا أتقنت هذه الأساسيات، فستصبح قراءة ومعالجة النصوص في C أوضح وأسهل وأكثر أمانًا.