Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

منشئ نصوص ديناميكي

جزء من قسم البرمجة كائنية التوجه في رحلة C على Coddy. الدرس 59 من 61.

challenge icon

التحدي

سهل

لنبنِ 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. ثم ادمج النص الجديد باستخدام strcat
    • get_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'.

سيستقبل برنامجك:

  1. عدد السلاسل النصية المطلوب إجراء append لها
  2. كل سلسلة في سطر منفصل

مثال على المخرجات عندما تكون المدخلات 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;
}

جميع دروس البرمجة كائنية التوجه

تدرّب بنفسك: مترجم C عبر الإنترنت