C++: سلاسل C

آخر تحديث: 2026-08-26

C++ لديها نوعان من السلاسل النصية:

  1. سلاسل C (مصفوفات محارف)
  2. سلسلة C++ (ستُغطى لاحقًا)

هذا الدرس يغطي سلاسل C أولًا — أنها إرث من C تحافظ عليه C++ للتوافق. فهمها يساعدك على إدراك المبادئ الأساسية للسلاسل النصية.



1. ما هي سلسلة C؟

(1) 1.1 الجوهر: مصفوفة محارف + منتهية بقيمة فارغة

سلسلة C هي ببساطة مصفوفة محارف، مع قاعدة خاصة:

TEXT 📖 للعرض فقط
"Hello" in memory:
+---+---+---+---+---+----+
| H | e | l | l | o | \0 |
+---+---+---+---+---+----+
 0 1 2 3 4 5 ← indices

💡 نقطة مهمة: طول سلسلة C هو 5 (Hello)، لكن حجم المصفوفة يجب أن يكون 6 على الأقل (لتخزين \0).



2. التعريف والتهيئة

(1) 2.1 تعريف سلسلة C

الصياغة:

TEXT 📖 للعرض فقط
char stringName[Size];

مثال:

▶ مثال 2: تطبيق برمجي أساسي (صعوبة ⭐)

CPP
#include <iostream>

int main() {
 char name[20]; // Can store 19 chars + 1 \0
 
 name[0] = 'H';
 name[1] = 'e';
 name[2] = 'l';
 name[3] = 'l';
 name[4] = 'o';
 name[5] = '\0'; // Don't forget the null terminator!
 
 std::cout << "Name: " << name << std::endl; // Hello
 
 return 0;
}
▶ جرّب الكود

الخرج:

TEXT 📖 للعرض فقط
Name: Hello

💡 نصيحة: إضافة \0 يدويًا مملة — ستتعلم طرقًا أبسط لاحقًا.

(2) 2.2 تهيئة سلسلة C

الطريقة 1: التهيئة بثابت سلسلة نصية

CPP
#include <iostream>

int main() {
 char name = "Hello"; // ✅ Compiler auto-adds \0, array size is 6
 
 std::cout << "Name: " << name << std::endl;
 
 return 0;
}

💡 نقطة مهمة: عند التهيئة بثابت سلسلة نصية، لا تحتاج لتحديد حجم المصفوفة — المترجم يحسبه تلقائيًا (بما في ذلك \0).



3. دوال السلاسل النصية الشائعة

دوال سلاسل C موجودة في ملف الرأس cstring.

(1) 3.1 strlen: حساب طول السلسلة

TEXT 📖 للعرض فقط
#include <iostream>
#include <cstring> // Must include this header

int main() {
 char name = "Hello";
 
 std::cout << "String: " << name << std::endl;
 std::cout << "Length: " << std::strlen(name) << std::endl; // 5(excluding \0)
 
 return 0;
}

💡 نصيحة: std::strlen تُرجع عدد المحارف الفعّالة (بدون \0)، بينما sizeof تُرجع حجم المصفوفة (بما في ذلك \0).

CPP
char name = "Hello";
std::cout << sizeof(name) << std::endl; // 6(Array size)
std::cout << std::strlen(name) << std::endl; // 5(effective character count)

(2) 3.2 strcpy: نسخ سلسلة

TEXT 📖 للعرض فقط
#include <iostream>
#include <cstring>

int main() {
 char src = "Hello";
 char dest[20];
 
 std::strcpy(dest, src); // Copy src to dest
 
 std::cout << "src:" << src << std::endl;
 std::cout << "dest:" << dest << std::endl;
 
 return 0;
}

⚠️ تحذير: std::strcpy لا تتحقق من حجم المصفوفة الهدف — إذا كان dest صغيرًا جدًا، ستسبب فيضان المخزن المؤقت!

دالة أكثر أمانًا (بعد C++11):

CPP
std::strncpy(dest, src, sizeof(dest) - 1); // Copy at most sizeof(dest)-1 characters
dest[sizeof(dest) - 1] = '\0'; // Manually add null terminator

(3) 3.3 strcat: ربط السلاسل

TEXT 📖 للعرض فقط
#include <iostream>
#include <cstring>

int main() {
 char greeting[50] = "Hello, ";
 char name = "World";
 
 std::strcat(greeting, name); // Append name to greeting
 
 std::cout << greeting << std::endl; // Hello, World
 
 return 0;
}

(4) 3.4 strcmp: مقارنة السلاسل

CPP
#include <iostream>
#include <cstring>

int main() {
 char str1 = "Hello";
 char str2 = "Hello";
 char str3 = "World";
 
 std::cout << "strcmp(str1, str2) = " << std::strcmp(str1, str2) << std::endl;
 std::cout << "strcmp(str1, str3) = " << std::strcmp(str1, str3) << std::endl;
 
 return 0;
}

قيم الإرجاع:

💡 نصيحة: لا تستخدم == لمقارنة سلاسل C! == تُقارن العناوين، وليس المحتوى.

TEXT 📖 للعرض فقط
char str1 = "Hello";
char str2 = "Hello";

if (str1 == str2) { // ❌ Error: Comparing addresses, not content
 // ...
}

if (std::strcmp(str1, str2) == 0) { // ✅ Correct:Use strcmp to compare content
 // ...
}


4. التعامل مع سلاسل C باستخدام cin و cout

(1) 4.1 قراءة السلاسل

CPP
#include <iostream>

int main() {
 char name[20];
 
 std::cout << "Please enter your name: ";
 std::cin >> name; // ✅ Can read strings (but no spaces)
 
 std::cout << "Hello," << name << "!" << std::endl;
 
 return 0;
}

💡 مشكلة: cin >> يتوقف عند المسافات! إذا أدخلت "John Smith"، سيقرأ فقط "John".

الحل: استخدم std::cin.getline

CPP
#include <iostream>

int main() {
 char name[50];
 
 std::cout << "Please enter your full name: ";
 std::cin.getline(name, 50); // ✅ Read entire line (including spaces)
 
 std::cout << "Hello," << name << "!" << std::endl;
 
 return 0;
}


5. تطبيق: معالجة بسيطة للسلاسل

▶ مثال 1: عد حروف العلة في سلسلة (صعوبة ⭐⭐)

CPP
#include <iostream>
#include <cstring>

int main() {
 char str[100];
 std::cout << "Please enter a string: ";
 std::cin.getline(str, 100);
 
 int vowels = 0;
 for (int i = 0; i < std::strlen(str); i++) {
 char c = str[i];
 if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u' ||
 c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U') {
 vowels++;
 }
 }
 
 std::cout << "Vowel count: " << vowels << std::endl;
 
 return 0;
}
▶ جرّب الكود

الخرج:

TEXT 📖 للعرض فقط
Please enter a string: 
Vowel count: 

نتيجة التشغيل:

TEXT 📖 للعرض فقط
Please enter a string: Hello World
Vowel count: 3


6. الأخطاء الشائعة

(1) 6.1 نسيان ترك مساحة لـ \0

مثال خطأ:

TEXT 📖 للعرض فقط
#include <iostream>

int main() {
 char name[5] = "Hello"; // ❌ Error: "Hello" Need 6 chars (including \0), but array size is only 5
 std::cout << name << std::endl;
 return 0;
}

الإصلاح:

CPP
char name[6] = "Hello"; // ✅ Correct:Array size must be at least 6

(2) 6.2 استخدام = لإسناد سلسلة

مثال خطأ:

TEXT 📖 للعرض فقط
#include <iostream>

int main() {
 char str1[20];
 char str2 = "Hello";
 
 str1 = str2; // ❌ Error: Cannot assign to array
 str1 = "World"; // ❌ Error: Cannot assign to array
 
 return 0;
}

الإصلاح: استخدم strcpy

CPP
#include <iostream>
#include <cstring>

int main() {
 char str1[20];
 char str2 = "Hello";
 
 std::strcpy(str1, str2); // ✅ Correct:Use strcpy to copy
 std::cout << str1 << std::endl;
 
 return 0;
}

❓ أسئلة شائعة

س: متى أستخدم سلاسل C، ومتى أستخدم سلاسل C++؟ ج: فضّل سلاسل C++ (ستُغطى لاحقًا)، إلا إذا: > 1. كنت تُصيح كودًا قديمًا (كود C) > 2. كنت تقوم بتحسين منخفض المستوى جدًا (سلاسل C أكثر كفاءة)

سلاسل C++ أكثر أمانًا وسهولة في الاستخدام؛ موصى بها للمبتدئين.

س: لماذا char name = "Hello" يعمل، لكن int arr = {1, 2, 3} لا يعمل؟ ج: فقط ثوابت السلاسل النصية يمكنها تهيئة مصفوفات المحارف مباشرة.

CPP
char name = "Hello"; // OK
int arr = {1, 2, 3}; // OK(this is an initializer list, not a string literal)

س: كيف أحول سلسلة C إلى سلسلة C++؟

ج: يمكنك الإسناد مباشرة (منشئ سلسلة C++ يتعامل مع التحويل تلقائيًا).

CPP
`#include <iostream>`
`#include <string>`

`int main() {`
    `char cstr[] = "Hello";`
    `std::string cppStr = cstr;  // Automatic conversion`

    `std::cout << cppStr << std::endl;`
    `return 0;`
`}`

▶ مثال 3: طول السلسلة والنسخ (صعوبة ⭐)

CPP
#include <iostream>
#include <cstring>

int main() {
    char src[] = "Hello";
    char dest[20];

    std::cout << "src length: " << strlen(src) << std::endl;

    strcpy(dest, src);
    std::cout << "After copy: " << dest << std::endl;

    return 0;
}
▶ جرّب الكود

الخرج:

TEXT 📖 للعرض فقط
src length: 5
After copy: Hello
💡 نصيحة: سلاسل C تستخدم strlen() للحصول على الطول و strcpy() للنسخ. تأكد أن المصفوفة الهدف كبيرة بما يكفي!


📖 ملخص


📝 تمارين

  1. أساسي (صعوبة ⭐): عرّف سلسلة C char str = "Hello, World!"، ثم أخرج طولها وكل محرف فيها.

  2. متوسط (صعوبة ⭐⭐): اكتب برنامجًا يتيح للمستخدم إدخال سلسلتين ومقارنة ما إذا كانتا متساويتين (باستخدام strcmp).

  3. تحدي (صعوبة ⭐⭐⭐): اكتب برنامجًا ينفذ "عكس السلسلة":

  4. دع المستخدم يدخل سلسلة نصية

  5. اعكسها (مثلاً، "Hello" تصبح "olleH")

  6. نفّذها باستخدام سلاسل C (لا يُسمح بسلسلة C++)


7. 🚀 الخطوة التالية

الآن بعد أن تعلمت سلاسل C، لنتابع إلى سلسلة C++ (الدرس 19) — صنف سلاسل نصية أكثر أمانًا وسهولة في الاستخدام!

Web-Tutorial.com

فريق Web-Tutorial التقني

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

100%