Presentation is loading. Please wait.

Presentation is loading. Please wait.

תכנות מערכות בשפת C מחרוזות מכללת אורט כפר-סבא אורי וולטמן

Similar presentations


Presentation on theme: "תכנות מערכות בשפת C מחרוזות מכללת אורט כפר-סבא אורי וולטמן"— Presentation transcript:

1 תכנות מערכות בשפת C מחרוזות מכללת אורט כפר-סבא אורי וולטמן
אורי וולטמן

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

3 חיפוש תו במחרוזת הפונקציה התקנית strchr, המוגדרת ב-string.h, מאפשרת לחפש תו מסוים בתוך מחרוזת. כותרת הפונקציה היא: char *strchr (const char *s, const char c) הפונקציה מחזירה מצביע למופע הראשון של התו c במחרוזת s, או מחזירה NULL אם התו לא מופיע במחרוזת. מה יהיה הפלט של קטע הקוד הבא? char str[] = “This is a sample string"; char *ptr; printf(“Looking for the 's' character\n”); ptr = strchr(str,’s’); while (ptr != NULL) { printf)"found at %d\n",ptr-str); ptr = strchr(ptr+1,’s’); }

4 חיפוש תו במחרוזת נממש את הפונקציה strchr:
char *strchr (const char *s, const char c) { while (*s != ‘\0’ && *s != c) s++; return ((*s == c) ? s : NULL); } סטודנט א' וסטודנט ב' מציעים לעשות שינוי בלולאת ה-while שמופיעה במימוש הנ"ל. ההצעה של סטודנט א': while (*s++ != ‘\0’ && *s != c) ; ההצעה של סטודנט ב': while (*s != ‘\0’ && *s++ != c) ; האם צריך המרצה לתת ציון שלילי לשני הסטודנטים? או רק לאחד מהם? או לאף אחד מהם?

5 חיפוש תת-מחרוזת הפונקציה התקנית strstr, המוגדרת ב-string.h, מאפשרת לחפש תת-מחרוזת בתוך מחרוזת מסוימת. כותרת הפונקציה היא: char *strstr (const char *haystack, const char *needle) הפונקציה מחזירה מצביע למופע הראשון של needle ב-haystack, או מחזירה NULL אם needle אינה תת-מחרוזת של haystack. אם needle היא מחרוזת ריקה, הפונקציה מחזירה מצביע לתחילת haystack. מה יהיה הפלט של קטע התכנית הבא? char s1[] = “This is a sample string"; puts(strstr(s1,”is”)); איזה שינוי יש לערוך בקטע התכנית, על מנת שהפלט יהיה "a sample string"? האם יש יותר מתשובה אחת לשאלה הקודמת?

6 העתקת מחרוזות לפעמים היינו רוצים להשתמש ב-strcpy(to,from), אבל להעתיק רק מספר מסוים של תווים מ-from, ולא את from כולו. לצורך כך קיימת ב-string.h פונקציה תקנית בשם strncpy, המתנהגת כמו strcpy, למעט זה שהיא מקבלת פרמטר שלישי n, הקובע את מספר התווים יועתקו. כותרת הפונקציה היא: char *strncpy (char *to, const char *from, unsigned int n) דוגמא לשימוש בפונקציה: char str[] ="This is a simple string"; char *pch = strstr(str,"simple"); strncpy(pch,"sample",6); puts(str); אם from קצרה מ-n בתים, אז יועתקו ‘\0’-ים (על מנת להשלים ל-n תווים). במידה ו-to ו-from נמצאים באזורים חופפים (ולו חלקית) בזיכרון, אז התנהגות הפונקציה אינה מוגדרת.

7 השוואת מחרוזות הכרנו קודם (ואף מימשנו) את הפונקציה strcmp המשווה בין שתי מחרוזות, שכותרתה: int strcmp (const char *s1, const char *s2) הפונקציה מקבלת שתי מחרוזות, משווה ביניהן, ומחזירה 0 אם שתי המחרוזות שוות, מס' שלילי אם s1 < s2, ומס' חיובי אם s1 > s2. השוואת מחרוזות נעשית לפי סדר מילוני(lexicographic order) : משווים בין האות הראשונה של שתי המחרוזות. אם האות הראשונה של s1 קודמת באלפבית לאות הראשונה של s2, אזי s1 < s2. ואם להיפך – אז s1 > s2 . אם לשתי המחרוזות אותה האות הראשונה, אז משווים בין האות השנייה, באופן דומה. לאחר מכן, אם עדיין מדובר באותיות שוות, ממשיכים באותו אופן לאות השלישית, וכו'. אם אחת המחרוזות נגמרה, בשעה שבמחרוזות השנייה עוד יש אותיות – אז המחרוזות השנייה גדולה מהראשונה. אם שתי המחרוזות נגמרו באותו זמן, מבלי שהתהליך נעצר קודם לכן, אזי המחרוזות שוות.

8 השוואת מחרוזות מה תחזיר הפונקציה strcmp עבור הזימונים הבאים:
strcmp(“hello”,”world”) < 0 strcmp(“hello”,”hello”) strcmp(“hello”,”Hello”) > 0 הסיבה שעבור הזימון האחרון לא החזירה הפונקציה strcmp את הערך 0, היא שהתו 'H' והתו 'h' הם שני תווים שונים לגמרי מבחינתה (הם ממוקמים במקומות שונים בטבלת ASCII). אם נרצה שהפונקציה strcmp תחזיר 0 עבור זימון זה, כלומר – שהיא לא תהיה רגישה לגודל אות (case insensitive), נשתמשו במקומה בפונקציה stricmp.

9 השוואת מחרוזות מוגדרת הפונקציה:
int stricmp (const char *s1, const char *s2) הפונקציה מתנהגת ממש כמו strcmp, כלומר: היא מקבלת שתי מחרוזות, משווה ביניהן, ומחזירה 0 אם שתי המחרוזות שוות, מס' שלילי אם s1 < s2, ומס' חיובי אם s1 > s2. ההבדל היחיד הוא שהפונקציה אינה מבדילה בין אותיות קטנות ואותיות גדולות ('A' מבחינתה זהה לגמרי ל-'a', 'B' זהה ל-'b', וכו'). איך נממש את הפונקציה? נקצה זיכרון (ע"י malloc שב-stdlib.h) לשתי מחרוזות זמניות t1 ו-t2 נעתיק את s1 ל-t1, ואת s2 ל-t2, אבל נהפוך כל אות לאות קטנה על-ידי שימוש בפונקציה הסטנדרטית tolower(), המוגדרת ב-ctype.h. כעת אנחנו בטוחים ש-t1 ו-t2 מכילות רק אותיות קטנות. נחזיר את הערך של strcmp(t1,t2).

10 השוואת מחרוזות מדוע מופיע '1+' ב-malloc?
int stricmp (const char *s1, const char *s2) { char *t1,*t2; t1 = malloc(strlen(s1) + 1); while (*s1) *t1++ = tolower(*s1++); *t1 = '\0'; t2 = malloc(strlen(s2) + 1); while (*s2) *t2++ = tolower(*s2++); *t2 = '\0'; return strcmp(t1,t2); } מדוע מופיע '1+' ב-malloc? מדוע לא מכפילים את הביטוי שמופיע בתוך ה-malloc בביטוי sizeof(char)? איזו שגיאה יש בפונקציה?

11 השוואת מחרוזות int stricmp (const char *s1, const char *s2) { char *t1,*t2; int returnvalue; t1 = malloc(strlen(s1) + 1); while (*s1) *t1++ = tolower(*s1++); *t1 = '\0'; t2 = malloc(strlen(s2) + 1); while (*s2) *t2++ = tolower(*s2++); *t2 = '\0'; return strcmp(t1,t2); free(t1); free(t2); return returnvalue; } נשים לב שאנחנו מזמנים כאן את malloc, אבל מבלי לבדוק האם הקצאת הזיכרון הצליחה (אולי הפונקציה החזירה NULL כי אין זיכרון פנוי?). יתרה מכך: המצביעים t1 ו-t2 מצביעים על סוף המחרוזת, ולא על תחילתה. איך ניתן לפתור את הבעיה? returnvalue = strcmp(t1,t2);

12 השוואת מחרוזות פונקציה נוספת המשווה שתי מחרוזות לפי סדר לקסיקוגרפי היא הפונקציה strncmp, שכותרתה: int strncmp (const char *s1, const char *s2, unsigned n) הפונקציה מקבלת שתי מחרוזות, ומשווה רק בין n התווים הראשונים של כל מחרוזת, ומחזירה 0 אם שתי המחרוזות שוות, מס' שלילי אם s1 < s2, ומס' חיובי אם s1 > s2. אם במחרוזת מסוימת יש פחות מ-n תווים, אז מתייחסים רק לתווים שעד ל-null terminator. אם בשתי המחרוזות יש פחות מ-n תווים, אין הבדל בין strncmp ל-strcmp. strncmp(“helloa”,”hellob”,5) 0 strncmp(“helloa”,”hellob”,6) < 0 strncmp(“helloa”,”hellob”,9) < 0

13 השוואת מחרוזות הפונקציה לא תעבוד כשורה... מה חסר?
int strncmp (const char *s1, const char *s2, unsigned int n) { char *t1, *t2; int returnvalue; t1 = malloc(strlen(s1) + 1); strncpy(t1,s1,n); t1[n] = '\0'; t2 = malloc(strlen(s2) + 1); strncpy(t2,s2,n); t2[n] = '\0'; returnvalue = strcmp(t1,t2); free(t1); free(t2); return returnvalue; } הפונקציה לא תעבוד כשורה מה חסר? גם כאן צריך היה לוודא שהקצאת הזיכרון הצליחה...

14 חיפוש תווים במחרוזת ב-string.h מוגדרת הפונקציה התקנית:
char *strpbrk (const char *str1, const char *str2) הפונקציה מחזירה מצביע למופע הראשון ב-str1 של תו מתוך str2. אם הפונקציה סרקה את str1, והגיעה עד ל-null terminator, מבלי שמצאה אף אחד מהתווים שבתוך str2, אז היא תחזיר NULL.

15 חיפוש תווים במחרוזת מה יהיה הפלט? #include <stdio.h>
#include <string.h> int main() { char str[] = "This is a sample string"; char key[] = "aeiou"; char *pch; printf ("Vowels in '%s': ",str); pch = strpbrk (str, key); while (pch != NULL) { printf ("%c " , *pch); pch = strpbrk (pch+1,key); } printf ("\n"); return 0; מה יהיה הפלט?

16 מציאת רישא מותנית פונקציה המוגדרת גם היא ב-string.h, היא:
unsigned int strspn (const char *str1, const char *str2) הפונקציה מחזירה את אורך הרישא (prefix) המקסימלית של str1, המורכבת כולה מתווים שנמצאים ב-str2. #include <stdio.h> #include <string.h> int main() { char str[] = “125th”, cset[] = " "; int i = strspn (str,cset); printf ("The length of the number is %d.\n",i); return 0; } אם התו הראשון של str1 אינו שייך ל-str2, אז הפונקציה תחזיר 0.

17 מציאת רישא מותנית פונקציה הפוכה ל-strspn, המוגדרת גם היא ב-string.h, היא: unsigned int strcspn (const char *str1, const char *str2) הפונקציה מחזירה את אורך הרישא (prefix) המקסימלית של str1, המורכבת כולה מתווים שאינם נמצאים ב-str2. #include <stdio.h> #include <string.h> int main() { char str[] = “fcba73”, cset[] = " "; int i = strcspn (str,cset); printf ("The first number is at position %d.\n",i+1); return 0; } הפונקציה סורקת גם את ה-‘\0’, ולכן היא תחזיר את האורך של str1 אם אף אחד מהתווים של str2 לא נמצאים ב-str1.


Download ppt "תכנות מערכות בשפת C מחרוזות מכללת אורט כפר-סבא אורי וולטמן"

Similar presentations


Ads by Google