Transcript Document
מחרוזות
קרן כליף
:ביחידה זו נלמד
מהי מחרוזת
איתחול מחרוזת
cin.getline
:string.h הספריה
strlen
strcpy
strcmp
strcat
מערך של מחרוזות
2
© Keren Kalif
מהי מחרוזת
מחרוזת הינה טיפוס שנועד לאחסן מילים שלמות
מחרוזת היא מקרה פרטי של מערך מטיפוס char
אבל התו האחרון במחרוזת תמיד יהיה ’( ‘\0קוד ה-
ASCIIשלו הוא )0
לכן מחרוזת גם נקראית Null Termianted String
מערך של תווים:
;}’char name[5] = {‘h’, ‘e’, ‘l’, ‘l’, ‘o
מחרוזת:
;}’char name[6] = {‘h’, ‘e’, ‘l’, ‘l’, ‘o’, ‘\0
העובדה שמחרוזת נגמרת ב ‘\0’ -מאפשרת לנו לרוץ
עליה מבלי לדעת את גודלה
3
© Keren Kalif
איתחול מחרוזת
ראינו כי אתחול מחרוזת יעשה כך:
;}'char str[] = {'h','e','l','l','o','\0
אך ניתן לאתחלה גם באופן הבא:
במקרה זה מוקצה מערך בגודל ,30ורק ב-
;”char str[] = “hello
5התאים הראשונים יש תווים ,ובשאר ,0
;”char str[30] = “hello
כמו איתחול חלקי של מערך
4
© Keren Kalif
1000
’‘h
1001
’‘e
1002
’‘l
1003
’‘l
1004
’‘o
1005
’‘\0
1006
4
char[]: str
int: x
)(void main
{
;”char str[] = “hello
;int x = 4
}
ריצה על מחרוזת
#include <iostream>
using namespace std;
void main()
{
char str[] = “hello”;
int i=0;
while (str[i] != '\0')
{
cout << str[i];
i++;
}
cout << "\n”;
}
5
© Keren Kalif
הדפסת מחרוזת
אבל כדי להדפיס את איבריה,מחרוזת היא אמנם מערך
!אין צורך בלולאה
#include <iostream>
using namespace std;
void main()
{
char str[] = “hello”;
cout << str << endl;
}
6
© Keren Kalif
הדפסת מחרוזת – נשים לב להבדל
#include <iostream>
using namespace std;
כאשר מדפיסים מחרוזת יודפסו איברי המערך עד
0 אשר הקומפיילר יתקל בתא שיש בו את הערך
,)‘\0’ שלASCII -(כלומר ערך ה
!\‘ בסוף המחרוזת0’ ולכן החשיבות של השמת
void main()
{
char str1[] = {'h','e','l','l','o'}; // doesn’t end with ‘\0’!!
char str2[] = "hello";
char str3[] = {'h','e','l','\0','l','o'}; // note the ‘\0’ in the middle
char str4[] = {'h','e','l',0,'l','o'}; // note the 0 in the middle
cout << str1 << endl;
cout << str2 << endl;
cout << str3 << endl;
cout << str4 << endl;
}
7
© Keren Kalif
קליטת מחרוזת
גם כדי לקלוט מחרוזת לא צריך לולאה:
)(void main
{
;]char str[10
;“ cout << "Please enter a string:
;cin >> str
;cout << "The string is: “ << str << endl
}
כאשר הפקודה cinמקבלת מערך תווים היא קוראת תווים עד אשר
יוקלד רווח מטיפוס כלשהו שיסמל את ה‘\0’ -
נשים לב שאורך המחרוזת שנכניס לא יהייה יותר גדול מגודל
המערך שהגדרנו ,כדי לא לדרוס תאים שלא הוקצו עבורו
8
© Keren Kalif
הפקודה cin.getline
עד כה ראינו כיצד ניתן לקרוא מילה שלמה (ללא רווחים),
לשמור אותה במערך ולהדפיסה
כעת נראה כיצד ניתן לבצע פעולות אלו גם עבור משפט
(מחרוזת הכוללת רווחים):
)(void main
{
;]char str[50
;“ cout << "Please enter a sentence:
;)cin.getline(str, 50
קולטת משפט עד ירידת שורה (' ,)'\nולא רק עד רווח.
תקלוט מקסימום 49תווים (מקום נוסף ל)'\0'-
;cout << "The sentence is:\n" << str << endl
9
© Keren Kalif
}
כמה מילים יש במשפט:דוגמא
רווח:(הנחה
)אחד בלבד מפריד בין מילה למילה ויש לפחות מילה אחת במשפט
void main()
{
char str[50];
int numOfWords=0, i=0;
cout << "Please enter a sentence: ";
cin.getline(str, 50);
while (str[i] != '\0')
{
if (str[i] == ‘ ‘)
numOfWords++;
i++;
}
numOfWords++;
}
cout << "There are “ << numOfWords
<< “ words in the sentence: “ << str << endl;
10
© Keren Kalif
כמה מילים יש במשפט:דוגמא
רווח:(הנחה
)אחד בלבד מפריד בין מילה למילה ויש לפחות מילה אחת במשפט
void main()
{
char str[50];
int numOfWords=0, i=0;
cout << "Please enter a sentence: ";
cin.getline(str, 50);
while (str[i] != '\0')
:תזכורת שאפשר גם כך
{
if (str[i++] == ' ')
numOfWords++;
}
numOfWords++;
}
cout << "There are “ << numOfWords
<< “ words in the sentence: “ << str << endl;
11
© Keren Kalif
,(בלי הנחות
כמה מילים יש במשפט:דוגמא
) כל מקרי הקצה מטופלים
void main()
}
char str[50];
int numOfWords=0, i=0;
cout << "Please enter a sentence: ";
cin.getline(str, 50);
while (str[i] != '\0')
}
if (str[i] != ' ') // check if this letter might be a beginning of a new word
}
if ( (i==0) ||
// if this is the first letter
(str[i-1] == ' ') ) // of if is a letter wit space before it
numOfWords++;
{
i++;
{
cout << "There are “ << numOfWords
<< “ words in the sentence: |“ << str << “|\n”;
{
12
© Keren Kalif
הספריה string.h
יש כל מיני פעולות נפוצות שניתן לבצע על מחרוזות ,כגון:
חישוב אורך ,העתקה ,שירשור וכד'
מאחר ואלו פעולות נפוצות ,שפת ++Cמספקת לנו
ספריה הנקראת string.hהמכילה פונקציות שעושות
את העבודה בשבילנו
פונקציה היא קופסא שחורה המקבלת נתונים ומחזירה
נתון אחר
למשל ,פונקציה המחזירה אורך של מחרוזת:
”“hello
13
© Keren Kalif
5
strlen הפונקציה
#include <string.h>
מקבלת מחרוזת ומחזירה אתstrlen הפונקציה
\‘ הראשון שבו נתקלה0’ -מספר התווים עד ה
void main()
{
char str1[] = "hello", str2[20], str3[]={'h','I','\0','h','I'};
int
len1, len2, len3;
cout << "Please enter a string: “;
cin.getline(str2, 20);
len1 = strlen(str1);
len2 = strlen(str2);
len3 = strlen(str3);
cout << "The len of |” << str1 << “| is “ << len1 << endl;
cout << "The len of |” << str2 << “| is “ << len2 << endl;
cout << "The len of |” << str3 << “| is “ << len3 << endl;
}
14
© Keren Kalif
strlen הפונקציה
#include <string.h>
:וכמובן שאפשר גם כך
void main()
{
char str1[] = "hello", str2[20], str3[]={'h','I','\0','h','I'};
// int len1, len2, len3;
cout << "Please enter a string: “;
cin.getline(str2, 20);
// len1 = strlen(str1);
// len2 = strlen(str2);
// len3 = strlen(str3);
cout << "The len of |” << str1 << “| is “ << strlen(str1) << endl;
cout << "The len of |” << str2 << “| is “ << strlen(str2) << endl;
cout << "The len of |” << str3 << “| is “ << strlen(str3) << endl;
}
15
© Keren Kalif
הפונקציה strcpy
ראינו שכדי להעתיק מערכים צריך לעבור בלולאה איבר-
איבר
עבור מחרוזות הספריה string.hמספקת לנו פונקציה
המעתיקה תוכן מחרוזת אחת לאחרת בפקודה אחת:
)strcpy(dest, src
destהיא המחרוזת אליה נרצה להעתיק
srcהיא המחרוזת ממנה נרצה להעתיק
במקרה זה "הקופסא השחורה" מקבלת 2מחרוזות,
מעדכנת את המחרוזת destומחזירה אותה
dest
src
16
© Keren Kalif
dest
דוגמא- strcpy הפונקציה
#include <string.h>
void main()
{
char str1[]="hello", str2[10];
cout << "Before copy: str1=|" << str1
<< "|, str2=|" << str2 << "|\n";
strcpy(str2, str1);
cout << "After copy: str1=|" << str1
<< "|, str2=|" << str2 << "|\n";
}
17
© Keren Kalif
הפונקציה - strcpyדגשים
גם פה יש חשיבות לכך שהמחרוזת מסתיימת ב‘\0’ -
וההעתקה מבוצעת עד ה ‘\0’ -בלבד
אחריות המתכנת לוודא כי ב dest -מספיק מקום להכיל
את !srcהקומפיילר לא מתריע על כך ,ובזמן ריצה אנו
עלולים לדרוס זיכרון שאינו שלנו!
18
© Keren Kalif
דגשים- strcpy הפונקציה
#include <string.h>
void main()
{
char str1[]={'h','e',0,'l','l','o',0}, str2[8];
cout << "Before copy: str1=|" << str1
<< "|, str2=|" << str2 << "|\n";
strcpy(str2, str1);
cout << “After copy: str1=|" << str1
<< "|, str2=|" << str2 << "|\n";
}
19
© Keren Kalif
char[]: str1
char[]: str2
‘h’
1000
‘e’
1001
0
1002
‘l’
1003
‘l’
1004
‘o’
1005
0
1006
‘h’
??
1007
‘e’
??
1008
??
0
1009
??
1010
??
1011
??
1012
??
1013
??
1014
הפונקציה strcat
פונקציה זו משרשרת מחרוזת אחת לסופה של אחרת:
)strcat(dest, src
destהיא המחרוזת אליה נרצה לשרשר לסופה
srcהיא המחרוזת אותה נרצה להעתיק
גם במקרה זה "הקופסא השחורה" מקבלת 2מחרוזות,
מעדכנת את המחרוזת destומחזירה אותה
dest
src
20
© Keren Kalif
dest
דוגמא- strcat הפונקציה
#include <string.h>
void main()
{
char str1[20], str2[10];
cout << "Please enter 2 strings: ";
cin >> str1 >> str2;
cout << "Before: str1:\t |" << str1
<< "|\t str2: |" << str2 << "|\n";
strcat(str1, str2);
cout << "Before: str1:\t |" << str1
<< "|\t str2: |" << str2 << "|\n";
}
21
© Keren Kalif
רווח
הוספת
–
strcat
הפונקציה
#include <string.h>
void main()
{
char str1[20], str2[10];
cout << "Please enter 2 strings: ";
cin >> str1 >> str2;
cout << "Before: str1:\t |" << str1
<< "|\t str2: |" << str2 << "|\n";
strcat(str1, “ “);
strcat(str1, str2);
cout << “After: str1:\t |" << str1
<< "|\t str2: |" << str2 << "|\n";
}
22
© Keren Kalif
הפונקציה - strcatדגשים
בדיוק כמו הדגשים של :strcpy
23
© Keren Kalif
גם פה יש חשיבות לכך שהמחרוזת מסתיימת ב‘\0’ -
והשירשור מבוצע עד ה ‘\0’ -של המחרוזת המועתקת
בשירשור אנו דורסים את ה ‘\0’ -של המחרוזת אליה
משרשרים
אחריות המתכנת לוודא כי ב dest -מספיק מקום להכיל את
!srcהקומפיילר לא מתריע על כך ,ובזמן ריצה אנו עלולים
לדרוס זיכרון שאינו שלנו!
הרצה- strcat הפונקציה
#include <string.h>
char[]: str1
void main()
{
char str1[]={'h','e',0,'l','l','o',0}, str2[10]="hi";
cout << "Before cat: str1:\t |" << str1
<< "|\t str2: |" << str2 << "|\n";
strcat(str2, str1);
}
cout << “After cat: str1:\t |" << str1
<< "|\t str2: |" << str2 << "|\n";
24
© Keren Kalif
char[]: str2
‘h’
1000
‘e’
1001
0
1002
‘l’
1003
‘l’
1004
‘o’
1005
0
1006
‘h’
1007
‘i’
1008
‘h’
0
1009
‘e’
0
1010
0
1011
0
1012
0
1013
0
1014
דוגמא לשימוש בערך המוחזר מstrcat -
עפ"י ההצהרה הרשמית ,הפונקציות strcpyוstrcat -
מחזירות את המחרוזת אותן שינו
ברוב המקרים לא משתמשים בערך מוחזר זה (כי הנתון
המקורי בכל מקרה התעדכן)
>#include <string.h
)(void main
{
;"char str1[20]="hello", str2[20]="world
;)strcat(strcat(str1, " "), str2
;(“ “ strcat(str1,
;)strcat(str1, str2
;”cout << "str1 : |” << str1 << “|\n
25
© Keren Kalif
{
הפונקציה strcmp
השוואה בין מחרוזות היא השוואה לקסיקוגרפית (ולא לפי
אורך המילה)
כדי להשוות בין מספרים או תווים השתמשנו באופרטורים
<!=,==,=<,=<,<,
כדי להשוות בין מחרוזות לא נשתמש באופרטורים אלו,
אלא בפונקציה ,strcmpשהיא "הקופסא השחורה"
הבאה:
str1
str2
26
© Keren Kalif
1/0/-1
הפונקציה )2( strcmp
הפונקציה מקבלת 2מחרוזות ,ומחזירה:
0אם הם שוות
1אם הראשונה גדולה מהשניה (כלומר במילון str1תופיע
אחרי )str2
-1אם הראשונה קטנה מהשניה (כלומר במילון str1תופיע
לפני )str2
דוגמאות:
27
© Keren Kalif
” str1=“hello”, str2=“worldיוחזר -1
” str1=“world”, str2=“helloיוחזר 1
” str1=“hello”, str2=“helloיוחזר 0
יוחזר 1
”str1=“zz”, str2=“aaa
יוחזר -1
”str1=“bb”, str2=“bbb
דוגמא- strcmp הפונקציה
#include <string.h>
void main()
{
char str1[10], str2[10];
int res
bool fContinue=true;
while (fContinue)
{
cout << "Please enter 2 strings, or '!' to exit: “;
cin >> str1 >> str2;
if (strcmp(str1, “!") == 0 && strcmp(str2, “!") == 0)
fContinue = false;
else
{
res = strcmp(str1, str2);
cout << "The result of strcmp(str1, str2): “ << res << endl;
}
}
28
}
© Keren Kalif
אפסים שונים
המספר 0ייוצג בזכרון ב 4 -בתים כמספר :0
00000000
00000000
00000000
00000000
התו '( '0ערכו האסקיי )48ייוצג בזכרון בבית אחד:
00110000
התו ’( ‘\0ערכו האסקיי )0ייוצג בזכרון בבית אחד:
00000000
המחרוזת " "0תייוצג בזכרון ע"י 2בתים ,מאחר וזו
מחרוזת שהתו הראשון שלה מייצג את התו ' '0והתא
השני את התו ’‘\0
00110000 00000000
29
© Keren Kalif
30
© Keren Kalif
מערך של מחרוזות
אם נרצה לשמור טקסט בשורות נפרדות ,נשתמש במערך
של מחרוזות
זוהי למעשה מטריצה של תווים
למשל מטריצה עם LINESשורות ,ובכל שורה מקסימום
LETTERS_MAXתווים:
;]char text[LINES][MAX_LETTERS
כדי לפנות לתא מסוים במטריצה נפנה ע"י ]text[i][j
כדי לפנות לשורה שלמה (מחרוזת אחת) ,שהיא למעשה
איבר במערך של מחרוזות נפנה ע"י ]text[i
31
© Keren Kalif
שורות בהן
- מערך של מחרוזות – דוגמא
const int LINES
= 3;
const int MAX_LETTERS = 81;
מופיע תו מסוים
void main()
{
char text[LINES][MAX_LETTERS], ch;
cout << "Please enter " << LINES << " lines:\n";
for (int i=0 ; i < LINES ; i++)
cin.getline(text[i], MAX_LETTERS);
cout << "Please enter a charchter to search: ";
cin >> ch;
}
for (int i=0 ; i < LINES ; i++)
{
for (int j=0 ; text[i][j] != '\0' ; j++)
{
if (text[i][j] == ch)
{
cout << "The char " << ch << " appears in the line: |" << text[i] << "|\n";
break; // stops inner for..
}
}
}
32
© Keren Kalif
מצא את
– מערך של מחרוזות – דוגמא
) יש לפחות שורה אחת בטקסט:השורה הארוכה ביותר (הנחה
const int LINES
= 3;
const int MAX_LETTERS = 81; ‘h’
‘e’
‘l’
‘l’
‘o’
‘‘
‘w’
‘o’
‘r’
‘l’
‘d’
‘\0’
0
0
‘g’
‘o’
‘o’
‘d’
‘‘
‘m’
‘o’
‘r’
‘n’
‘i’
‘n’
‘g’
‘\0’
0
‘‘
‘h’
‘i’
‘\0’
0
0
0
0
0
void main()
‘h’
‘i’
‘‘
‘h’
‘i’
{
char text[LINES][MAX_LETTERS];
int maxLineLen=0, maxLineIndex, currentLen;
cout << "Please enter " << LINES << " lines:\n";
for (int i=0 ; i < LINES ; i++)
cin.getline(text[i], MAX_LETTERS);
}
// find the longest line
for (int i=0 ; i < LINES ; i++)
{
currentLen = strlen(text[i]);
if (currentLen > maxLineLen)
{
maxLineLen = currentLen;
maxLineIndex = i;
}
}
cout << "Longest line is #" << maxLineIndex+1 << " and is |"
<< text[maxLineIndex] << "|\n";
33
© Keren Kalif
בעיה נפוצה
34
© Keren Kalif
התוכנית משום-מה קלטה שורה אחת פחות,
ובהדפסה דילגה על השורה הראשונה..
הפתרון
ניקוי האנטר שבבאפר
35
© Keren Kalif
:ביחידה זו למדנו
מהי מחרוזת
איתחול מחרוזת
cin.getline
:string.h הספריה
strlen
strcpy
strcmp
strcat
מערך של מחרוזות
36
© Keren Kalif
תרגיל :1
הגדר מטריצה של תווים (מערך של מחרוזות) וקרא לתוכו
קלט
הגדר מחרוזת וקרא לתוכה קלט
הדפס כמה שורות במטריצה זהות למחרוזת
דוגמא:
37
© Keren Kalif
תרגיל :2
כתוב תוכנית המגדירה 3מערכים של מחרוזות (מטריצות)
) (text1, text2, text3באותו הגודל וקרא נתונים ל 2-המטריצות
הראשונות
הפונקציה תשים מחרוזות ב text3-באופן הבא:
במידה והאורך הכולל של השורה המתאימה ב text1 -וב text2 -קטן מאורך
שורה אפשרית ,נעתיק את השורה המתאימה מ text1 -ל text3 -ואח"כ
נשרשר את השורה המתאימה מ .text2 -אחרת נשים ב text3 -שורה ריקה.
לבסוף התוכנית תדפיס את text3
שימו לב :אין "להמציא את הגלגל
מחדש"!!
38
© Keren Kalif
תרגיל :3
כתוב תוכנית המגדירה מערך של מחרוזות .יש לסובב את
איברי המערך כך שבשורה השניה תהיה המחרוזת
הראשונה ,בשורה השלישית המחרוזת השניה וכו' .השורה
האחרונה תועתק במקום המחרוזת הראשונה
לבסוף התוכנית תדפיס את המערך המעודכן
39
© Keren Kalif