منشئ نصوص ديناميكي
جزء من قسم البرمجة كائنية التوجه في رحلة C على Coddy. الدرس 59 من 61.
التحدي
سهللنبنِ StringBuilder: حاوية dynamic للسلاسل النصية تنمو تلقائيًا كلما أجريت append للنص. هذه أداة عملية تجمع بين إدارة الذاكرة dynamic وأنماط OOP التي أتقنتها طوال هذه الدورة.
ستنظّم شيفرتك عبر ثلاثة ملفات:
stringbuilder.h: Declare البنيةStringBuilderمع ثلاثة أعضاء: مخزنchar*، وsize_tللقيمة current للطول، وsize_tللسعة الإجمالية capacity. Declare نماذج functions لإنشاء StringBuilder، وإجراء append للنص إليه، واسترداد السلسلة النصية النهائية، وتحرير الذاكرة. حواجز التضمين ضرورية.stringbuilder.c: Implement نظام StringBuilder الخاص بك:create_stringbuilder: تخصّص StringBuilder على heap، وتُهيّئ buffer بسعة أولية قدرها 16 بايت، وتضبط length على 0، وتضمن أن يبدأ buffer كسلسلة نصية empty (منتهية بـ null)append: تستقبل مؤشّرًا إلى StringBuilder وسلسلة نصية لإجراء append لها. Calculate الطول المطلوب الجديد. إذا كان exceeds capacity، فقم بمضاعفة capacity (بشكل متكرر إذا لزم الأمر) واستخدمreallocلتكبير buffer. ثم ادمج النص الجديد باستخدامstrcatget_string: تُعيد مؤشّرًا إلى buffer الداخلي (وصول للقراءة فقط)free_stringbuilder: تحرّر buffer أولًا، ثم بنية StringBuilder نفسها
main.c: اقرأ عددًا صحيحًا يحدّد عدد السلاسل النصية المطلوب إجراء append لها. ثم اقرأ كل سلسلة باستخدامfgetsوأجرِ append لها إلى StringBuilder. بعد إضافة جميع السلاسل، اطبع السلسلة النصية complete assembled باستخدامget_string. وأخيرًا، حرّر StringBuilder.
اثنتان من أهم functions المستخدمة في هذا التحدي:
realloc(ptr, new_size): تغيّر حجم كتلة من الذاكرة allocated مسبقًا. تستقبل مؤشّرًا إلى الكتلة الموجودة والحجم الجديد المطلوب بالبايت، وتُعيد مؤشّرًا إلى الكتلة التي أُعيد تغيير حجمها (والتي قد تكون قد نُقلت). استخدمها فيappendعندما يحتاج buffer إلى grow:sb->buffer = (char*)realloc(sb->buffer, sb->capacity);fgets(buffer, size, stream): تقرأ سطرًا من النص من تدفّق إدخال إلى مصفوفة من character، وتتوقف عند سطر جديد أو عند قراءةsize - 1من الأحرف. وهي تُبقي character السطر الجديد في buffer، لذا ستحتاج إلى إزالته يدويًا. استخدمها فيmain.cلقراءة كل سلسلة إدخال:fgets(line, sizeof(line), stdin);
لإزالة سطر النهاية الجديد: تحقّق مما إذا كان character الأخير هو'\n'واستبدله بـ'\0'.
سيستقبل برنامجك:
- عدد السلاسل النصية المطلوب إجراء append لها
- كل سلسلة في سطر منفصل
مثال على المخرجات عندما تكون المدخلات 3، ثم Hello، ، World:
Hello Worldمثال على المخرجات عندما تكون المدخلات 4، ثم C، is، a، great language!:
C is a great language!مثال على المخرجات عندما تكون المدخلات 1، ثم SingleString:
SingleStringتذكّر تحديث الحقل length بعد كل عملية append. عند التحقّق مما إذا كانت إعادة التخصيص مطلوبة، احسب حساب null terminator: يحتاج buffer إلى مساحة قدرها length + new_text_length + 1 بايت. استخدم strlen من <string.h> لقياس أطوال السلاسل النصية. استدعِ أيضًا getchar() after scanf في main.c لاستهلاك سطر النهاية المتبقي قبل قراءة السلاسل باستخدام fgets.
جرّب بنفسك
#include <stdio.h>
#include <stdlib.h>
#include "stringbuilder.h"
int main() {
int n;
scanf("%d", &n);
getchar(); // استهلك السطر الجديد بعد الرقم
// TODO: Create a StringBuilder using create_stringbuilder()
// TODO: Read n strings and append each to the StringBuilder
// Hint: استخدم fgets أو ما شابه لقراءة كل سطر
// تذكر معالجة حرف السطر الجديد من fgets إذا استخدمته
// TODO: اطبع السلسلة المجمعة الكاملة باستخدام get_string()
// TODO: Free the StringBuilder using free_stringbuilder()
return 0;
}
جميع دروس البرمجة كائنية التوجه
1أساسيات البرمجة التركيبية
ملفات الترويسةحواجز التضمينملفات المصدرالدوال الساكنةمراجعة: آلة حاسبة تركيبية4التغليف (Encapsulation)
مفهوم الـ Opaque Pointersتعريف الـ Opaque Structsالـ Getters والـ Settersالتحقق من البيانات في الـ Settersملخص: الصندوق السري2الكائنات والأساليب
الـ Structs ككائناتمؤشر 'Self'صحة استخدام Constالمؤشر مقابل القيمةالأساليب المساعدةملخص: Point Manager5مشروع: حساب بنكي بسيط
إعداد المشروعتنفيذ الحساب3دورة حياة الكائن
نمط المنشئ (Constructor Pattern)نمط الهادم (Destructor Pattern)تهيئة الـ Stackالنسخ العميق (Deep Copy)مراجعة: String Wrapper6الوراثة عبر التركيب
تضمين الـ Structقاعدة العضو الأولالوصول إلى أعضاء الأبعملية الـ Upcastingمراجعة: هرمية الأشكال9مشروع: رسّام الأشكال
نظرة عامة على المشروعتنفيذ الدائرةتنفيذ المستطيلاستخدام تعدد الأشكالحاوية الأشكالتدرّب بنفسك: مترجم C عبر الإنترنت