בונה מחרוזות דינמי
חלק מהיחידה תכנות מונחה עצמים במסלול ה-C של Coddy. שיעור 59 מתוך 61.
אתגר
קלבואו נבנה StringBuilder: מכל להחזקת מחרוזת דינמי שגדל אוטומטית כשמוסיפים לו טקסט. זהו כלי שימושי ומעשי שמשלב ניהול זיכרון דינמי עם דפוסי ה-OOP שהתמקצעת בהם לאורך הקורס הזה.
תארגן את הקוד שלך בשלושה קבצים:
stringbuilder.h: הכרז על המבנהStringBuilderובו שלושה איברים: מאגרchar*, ערך מסוגsize_tעבור האורך הנוכחי, וערך מסוגsize_tעבור הקיבולת הכוללת. הכרז על אבות טיפוס של פונקציות ליצירת StringBuilder, להוספת טקסט אליו, לקבלת המחרוזת הסופית ולשחרור הזיכרון. הגנות הכללה הן חיוניות.stringbuilder.c: ממש את מערכת ה-StringBuilder שלך:create_stringbuilder: מקצה StringBuilder בערימה, מאתחלת את המאגר בקיבולת התחלתית של 16 בתים, מגדירה את האורך ל-0 ומוודאת שהמאגר מתחיל כמחרוזת ריקה (שמסתיימת בתו null)append: מקבלת מצביע ל-StringBuilder ומחרוזת להוספה. חשב את האורך החדש הנדרש. אם הוא חורג מהקיבולת, הכפל את הקיבולת (שוב ושוב אם צריך) והשתמש ב-reallocכדי להגדיל את המאגר. לאחר מכן שרשר את הטקסט החדש באמצעותstrcatget_string: מחזירה מצביע למאגר הפנימי (גישה לקריאה בלבד)free_stringbuilder: משחררת קודם את המאגר, ואז את מבנה ה-StringBuilder עצמו
main.c: קרא מספר שלם המציין כמה מחרוזות יש להוסיף. לאחר מכן קרא כל מחרוזת באמצעותfgetsוהוסף אותה ל-StringBuilder שלך. לאחר הוספת כל המחרוזות, הדפס את המחרוזת המורכבת המלאה באמצעותget_string. לבסוף, שחרר את ה-StringBuilder.
שתי פונקציות מפתח שמשמשות באתגר הזה:
realloc(ptr, new_size): משנה את גודלו של בלוק זיכרון שהוקצה קודם לכן. היא מקבלת מצביע לבלוק הקיים ואת הגודל החדש הרצוי בבתים, ומחזירה מצביע לבלוק שגודלו שונה (ייתכן שהועבר למקום אחר). השתמש בה ב-appendכאשר צריך להגדיל את המאגר:sb->buffer = (char*)realloc(sb->buffer, sb->capacity);fgets(buffer, size, stream): קוראת שורת טקסט מזרם קלט לתוך מערך תווים, ועוצרת בירידת שורה או לאחר שנקראוsize - 1תווים. היא משאירה את תו ירידת השורה במאגר, ולכן צריך להסיר אותו ידנית. השתמש בה ב-main.cכדי לקרוא כל מחרוזת קלט:fgets(line, sizeof(line), stdin);
כדי להסיר את ירידת השורה שבסוף: בדוק אם התו האחרון הוא'\n'והחלף אותו ב-'\0'.
התוכנית שלך תקבל:
- את מספר המחרוזות להוספה
- כל מחרוזת בשורה נפרדת
פלט לדוגמה כשהקלט הוא 3, אחריו Hello, , World:
Hello Worldפלט לדוגמה כשהקלט הוא 4, אחריו C, is, a, great language!:
C is a great language!פלט לדוגמה כשהקלט הוא 1, אחריו SingleString:
SingleStringזכור לעדכן את השדה length אחרי כל פעולת הוספה. כשבודקים אם יש צורך בהקצאה מחדש, יש להביא בחשבון את תו הסיום null: המאגר צריך להכיל מקום עבור length + new_text_length + 1 בתים. השתמש ב-strlen מתוך <string.h> כדי למדוד אורכי מחרוזות. בנוסף, קרא ל-getchar() אחרי scanf ב-main.c כדי לצרוך את ירידת השורה שנותרה לפני קריאת מחרוזות באמצעות fgets.
נסו בעצמכם
#include <stdio.h>
#include <stdlib.h>
#include "stringbuilder.h"
int main() {
int n;
scanf("%d", &n);
getchar(); // קלוט את תו ירידת השורה שאחרי המספר
// TODO: צור StringBuilder באמצעות create_stringbuilder()
// TODO: קרא n מחרוזות והוסף כל אחת מהן ל-StringBuilder
// רמז: השתמש ב-fgets או בפונקציה דומה כדי לקרוא כל שורה
// זכור לטפל בתו ירידת השורה שמתקבל מ-fgets אם אתה משתמש בה
// TODO: הדפס את המחרוזת המלאה שהורכבה באמצעות get_string()
// TODO: שחרר את ה-StringBuilder באמצעות free_stringbuilder()
return 0;
}
כל השיעורים ביחידה תכנות מונחה עצמים
4כימוס
המושג של מצביעים אטומיםהגדרת מבנים אטומיםפונקציות Get ו-Setאימות ב-Settersסיכום: הקופסה הסודית2אובייקטים ומתודות
מבנים כאובייקטיםמצביע 'Self'נכונות constמצביע לעומת ערךמתודות עזרחזרה: מנהל נקודות5פרויקט: חשבון בנק פשוט
הגדרת הפרויקטמימוש החשבוןתרגלו בעצמכם: קומפיילר C אונליין