ויקימחשבים
Advertisement

מחרוזת היא רצף של תווים. מחרוזות משמשות על פי רוב בתכנות ליצוג מילים ומשפטים.

מעט לגבי תווים[]

כבר ראינו שתו (char) הוא טיפוס בעל בית יחיד, המשמש לתווי א"ב או ערכים מספריים קטנים. אנו יכולים להחליט שלמספרים כלשהם יש משמעות מיוחדת מבחינתנו, אך את המחשב מעניינים רק הערכים המספריים של תו. במחשב כלשהו, לדוגמה, ערך התו 'a' יכול להיות 97. מבחינת מחשב זה, על כן, אין הבדל בין 'a' לבין 97.

בשפת C יש מוסכמה שעל פיה התו בעל הערך המספרים 0 הוא התו הריק. בפרק זה נראה שיש משמעות מיוחדת לתו הריק.


Achtung

שימו לב:

התו הריק 0 אינו תו הרווח ' '.


הגדרת מחרוזת[]

המחרוזת כמערך תווים[]

מחרוזת ב-C מוגדרת על ידי מערך של משתנים מסוג char. לדוגמה:

char my_string[5];

היא הכרזה על מערך בשם my_string בעל מקום ל5 תווים.

עם זאת, מחרוזת היא יותר מאשר סתם מערך תווים. שאר הנושא מדבר על כך.

חשיבות התו הריק[]

קיימת מוסכמה שמחרוזת היא יותר מאשר מערך של תווים. המוסכמה אומרת שתווי המחרוזת מתחלקים לשלושה חלקים:

  1. התווים עד לתו הריק הראשון
  2. התו הריק הראשון מסמן את סוף התווים "הנחשבים" במחרוזת
  3. מהתו הראשון ועד סוף המערך, מתעלמים מתווי המחרוזת

(על פי המוסכמה, אם המערך אינו מכיל את התו הריק, אז המחרוזת אינה חוקית).

מיד בהמשך נראה דוגמה לכך.

אורך מחרוזת[]

לפי המוסכמה, התו הריק הראשון מסמן את סוף התווים "הנחשבים" במחרוזת. לכן, אורכה של מחרוזת נחשב מספר התווים מתחילת המערך ועד (לא כולל) התו הריק הראשון במערך.

נשים לב לכן, שלמחרוזת יש שתי תכונות גודל:

  1. למחרוזת, כמו לכל מערך אחר, יש גודל, והוא קובע את המספר המקסימלי של התווים שהמחרוזת יכולה להחזיק.
  2. למרוזת יש גם אורך, שהוא מספר התווים עד לתו הריק הראשון, והוא קובע את אורך המחרוזת בפועל עבור תוכנה הנוכחי.

דוגמה[]

להלן מערך של 14 תווים, המורכב מ3 חלקים:

  1. תחילה מופיע הרצף "Shalom olam".
  2. לאחר מכן מופיע התו הריק.
  3. לבסוף, לאחר התו הריק מופיעים עוד תווים, שלפי המוסכמה אינם נחשבים לתוכן המחרוזת.
המחרוזת שלום עולם.


Thumbs up

עכשיו תורך:

מה גודל המערך הנ"ל, ומה אורך המחרוזת?




אתחול מחרוזת[]

היות שמחרוזת היא מערך, ניתן לאתחל אותה כפי שמאתחלים כל מערך, או, לחלופין, אפשר להשים ערכים לאיבריה ממש כמו לכל מערך אחר. בשני המקרים יש לאתחל או להשים גם את התו הריק.

לדוגמה, אם נרצה לאתחל את המחרוזת my_string ל"wiki", אפשר לאתחל אותה כך:

char my_string[5] = {'w', 'i', 'k', 'i', 0};

או, לחלופין, אפשר להשים ערכים לאיבריה כך:

my_string[0] = 'w';
my_string[1] = 'i';
my_string[2] = 'k';
my_string[3] = 'i';
my_string[4] = 0;

השפה גם מאפשרת צורת אתחול מיוחדת למחרוזות, הקריאה יותר משתי האפשרויות הקודמות:

char my_string[] = "wiki";

נשים לב שבשיטה האחרונה אין צורך לציין את גודל המחרוזת (הוא מחושב לבד על ידי המהדר, אם כי זו לא טעות לכתוב אותו), וכן לא כותבים מפורשות את התו 0 (המהדר לוקח אותו בחשבון).

נזכור, לכן, שבקטעי קוד מהצורה:

char my_string_1[10] = {'w', 'i', 'k', 'i', 0};
char my_string_2[] = "wiki";

תמיד יש לחשוב מהו גודל המערך ומה אורך המחרוזת.


Thumbs up

עכשיו תורך:

מהם גודלי המערכים ואורכי המחרוזות בקטע הקוד?




פונקציות בסיסיות לטיפול במחרוזות[]

עבודה עם מחרוזות כוללת לרוב את אותן המטלות. ספריות המערכת כוללות פונקציות שימושיות למטלות נפוצות. כדי להשתמש בפונקציות אלו, יש להוסיף לתחילת הקובץ את השורה:

#include <string.h>

מציאת אורך מחרוזת[]

הפונקציה strlen מחזירה את אורכה של מחרוזת נתונה. לדוגמה:

char str[15] = "Boker Tov!";
int length = strlen( str );
printf("%d\n", length);

ידפיס את המספר 10, שכן ישנם עשרה תווים עד לתו הריק הראשון.

העתקת מחרוזת[]

היות שמחרוזת היא מערך, אי אפשר להעתיק מחרוזת על ידי השמה פשוטה כמו במשתנים רגילים. קטע הקוד הבא, לדוגמה, אינו חוקי:

char source[] = "Shalom";
char dest[] = str1; /* ERROR! */

כדי להעתיק מחרוזת, יש להעתיק תו אחר תו. הפונקציה strcpy עושה זאת. לדוגמה:

char source[] = "Shalom";
char dest[15];

strcpy( dest, source );

printf("%s\n%s\n", source, dest);

ידפיס

Shalom
Shalom

strcpy מקבלת שתי מחרוזות, ומעתיקה את השנייה לתוך הראשונה, כולל תו סיום המחרוזת.

שרשור מחרוזות[]

הפונקציה strcat משרשרת מחרוזת אחת לסוף של מחרוזת אחרת:

char source[] = "olam";
char dest[30] = "Shalom ";
strcat( dest, source );
printf("%s\n%s\n", source, dest);

קוד זה ידפיס:

olam
Shalom olam

האיור הבא מראה את המחרוזות לפני ואחרי פעולת השרשור:

שרשור שלום ועולם

שים לב במיוחד לתווים הריקים.

פלט וקלט[]

פלט[]

הפונקציה printf[]

בפלט וקלט הכרנו את הפונקציה printf המאפשרת להציג ערכי משתנים על המסך. אפשר להשתמש בפונקציה זו לפלט מחרוזות. לציון משתנה מסוג מחרוזת בפקודת קלט/פלט משתמשים ב%s. לדוגמה:

char name[] = "Moshe";
printf("My name is %s\n", name);

קוד זה יציג על המסך את הפלט:

My name is Moshe

פונקציות אחרות[]

הספריה הסטנדרטית כוללת פונקציות נוספות לפלט מחרוזות, לדוגמה puts.

קלט[]

הפונקציה scanf[]

בפלט וקלט ראינו את הפונקציה scanf המאפשרת לקלוט ערכים למשתנים. אפשר להשתמש בפונקציה זו לקלט מחרוזות. לציון משתנה מסוג מחרוזת בפקודת קלט/פלט משתמשים ב%s. לדוגמה:

char name[10];
printf("Please enter your name:\n");
scanf("%9s", &name);

קוד זה יציג על המסך:

Please enter your name:

ויחכה לקלט מהמשתמש. עד 9 תווים ייקלטו למשתנה name, או, אם 9 התווים הראשונים כוללים רווח, רק התווים עד הרווח הראשון.


0px

כדאי לדעת:

נשים לב לקובע הרוחב 9 ב"%9s". גם אם המשתמש יקליד יותר תווים, הקלט לא ייגלוש מתחום המחרוזת name. נדבר על כך עוד בהבעייתיות המיוחדת בפונקציות קלט.


הפונקציה fgets[]

הפונקציה fscanf מאפשרת לקלוט מחרוזות עד הרווח הראשון. לפעמים רוצים לקלוט שורה שלמה, גם אם היא כוללת רווחים. לצורך כך אפשר להשתמש בfgets, כך:

char a[50];

fgets(a, 49, stdin);

הקריאה:

fgets(a, 49, stdin);

תקלוט עד 49 תווים. אם ב49 התווים הראשונים יש מעבר לשורה חדשה (על ידי Enter), ייקלטו רק התווים עד שם.


0px

כדאי לדעת:

לעת עתה נוכל להתעלם מהארגמונט השלישי של הפונקציה, stdin, נעסוק בו בפלט וקלט קבצים.


פונקציות אחרות[]

הספריה הסטנדרטית כוללת פונקציות נוספות לקלט מחרוזות, לדוגמה gets. לפני השימוש בהם, מומלץ לקרוא על הבעייתיות המיוחדת בפונקציות קלט.

זהירות בטיפול במחרוזות[]

גישה שגוייה לאיברי המחרוזת כמערך[]

כבר ראינו שבשפת C, אם מערך הוא בגודל 20, אז גישה לאיבר מעבר לכך, נניח 33, גולשת מתחום המערך, ויכולה לגרום לבעיות. חשוב להבין שקל מאד ליפול לבעיות אלו דווקא בעבודה עם מחרוזות. נתבונן, לדוגמה, בקטע הקוד הבא:

char src[] = "Hello, world!";
char dest[4];

strcpy(dest, src);

קטע קוד זה מכיל שגיאה, מפני שבמערך dest אין מספיק מקום להעתיק את תווי "Hello, world!".

המסקנה, על כן, היא שבעבודה עם מחרוזות, ובעיקר עם פונקציות המעתיקות דברים למחרוזות (לדוגמה, strcpy, strcat, או פונקציות הקלט שראינו) - יש לנהוג בזהירות רבה.

הבעייתיות המיוחדת בפונקציות קלט[]

עם תשומת לב מספיקה, אפשר להבטיח שמרבית הקריאות המטפלות במחרוזות יעבדו בצורה בטוחה. כך, לדוגמה, לפני כל קריאה לstrcpy, אפשר לבדוק את אורכי המחרוזות, ולבצע את הפעולה רק אם אין סכנת גלישה. ישנה בעייה מיוחדת בקלט, מפני שאין דרך לדעת מראש כמה תווים תקליד המשתמשת. קטע הקוד הבא, לדוגמה, משתמש בscanf ללא קובע רוחב:

char name[10];
printf("Please enter your name:\n");
scanf("%s", &name);

חשוב להבין שזהו קטע קוד בעייתי ביותר. בכלל, כשעוסקים בקלט מחרוזות (אולי על ידי שימוש בפונקציות ספריה אחרות), חשוב לשים לב לנקודה.


הפרק הקודם:
מערכים
מחרוזות
תרגילים
הפרק הבא:
מצביעים
Advertisement