תכנות מערכות בשפת c

17
תתתתת תתתתתת תתתתC אאא- אאאאא אאאא אאא אאאא אאאאאא[email protected] 02.11.14 אאאאאאא

Upload: yoko-santana

Post on 13-Mar-2016

47 views

Category:

Documents


1 download

DESCRIPTION

מכללת אורט כפר-סבא. תכנות מערכות בשפת C. מחרוזות. 02.11.14. אורי וולטמן. [email protected]. חידה לחימום. נתונות שתי ערימות של קוביות, כשבכל ערימה מספר הקוביות ההתחלתי הוא אקראי. - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: תכנות מערכות בשפת  C

תכנות מערכות Cבשפת

מכללת אורט כפר-סבא

אורי וולטמן[email protected]

02.11.14

מחרוזות

Page 2: תכנות מערכות בשפת  C

חידה לחימום נתונות שתי ערימות של קוביות, כשבכל ערימה מספר הקוביות

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

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

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

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

מנצח תמיד.

Page 3: תכנות מערכות בשפת  C

הפונקציה התקנית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’);}

חיפוש תו במחרוזת

Page 4: תכנות מערכות בשפת  C

נממש את הפונקציה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) ;

האם צריך המרצה לתת ציון שלילי לשני הסטודנטים? או רק לאחד מהם? אולאף אחד מהם?

חיפוש תו במחרוזת

Page 5: תכנות מערכות בשפת  C

הפונקציה התקנית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?"

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

חיפוש תת-מחרוזת

Page 6: תכנות מערכות בשפת  C

-לפעמים היינו רוצים להשתמש ב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 נמצאים באזורים חופפים )ולו חלקית( בזיכרון, אז התנהגות

הפונקציה אינה מוגדרת.

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

Page 7: תכנות מערכות בשפת  C

הכרנו קודם )ואף מימשנו( את הפונקציהstrcmp המשווה בין שתי מחרוזות, שכותרתה:

int strcmp (const char *s1, const char *s2) אם 0הפונקציה מקבלת שתי מחרוזות, משווה ביניהן, ומחזירה

s1, ומס' חיובי אם s1 < s2שתי המחרוזות שוות, מס' שלילי אם > s2.

השוואת מחרוזות נעשית לפי סדר מילוני(lexicographic order ): משווים בין האות הראשונה של שתי המחרוזות. אם האות הראשונה שלs1 קודמת

. s1 > s2. ואם להיפך – אז s1 < s2, אזי s2באלפבית לאות הראשונה של אם לשתי המחרוזות אותה האות הראשונה, אז משווים בין האות השנייה, באופן

דומה. ,לאחר מכן, אם עדיין מדובר באותיות שוות, ממשיכים באותו אופן לאות השלישית

וכו'. אם אחת המחרוזות נגמרה, בשעה שבמחרוזות השנייה עוד יש אותיות – אז

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

שוות.

השוואת מחרוזות

Page 8: תכנות מערכות בשפת  C

מה תחזיר הפונקציהstrcmp:עבור הזימונים הבאים

strcmp(“hello”,”world”) < 0

strcmp(“hello”,”hello”) 0

strcmp(“hello”,”Hello”) > 0

השוואת מחרוזות

הסיבה שעבור הזימון האחרון לא החזירה הפונקציהstrcmp היא שהתו '0 את הערך ,H' והתו 'h הם שני '

תווים שונים לגמרי מבחינתה )הם ממוקמים במקומות (.ASCIIשונים בטבלת

אם נרצה שהפונקציהstrcmp עבור זימון זה, 0 תחזיר caseכלומר – שהיא לא תהיה רגישה לגודל אות )

insensitive נשתמשו במקומה בפונקציה ,)stricmp.

Page 9: תכנות מערכות בשפת  C

:מוגדרת הפונקציהint stricmp (const char *s1, const char *s2)

הפונקציה מתנהגת ממש כמוstrcmp כלומר: היא מקבלת שתי , אם שתי המחרוזות שוות, מס' 0מחרוזות, משווה ביניהן, ומחזירה

.s1 > s2, ומס' חיובי אם s1 < s2שלילי אם ההבדל היחיד הוא שהפונקציה אינה מבדילה בין אותיות קטנות

', b' זהה ל-'a', 'B' מבחינתה זהה לגמרי ל-'Aואותיות גדולות )'וכו'(.

?איך נממש את הפונקציה ע"י( נקצה זיכרוןmalloc-שב stdlib.h לשתי מחרוזות זמניות )t1-ו t2 נעתיק אתs1-ל t1 ואת ,s2-ל t2 אבל נהפוך כל אות לאות קטנה ,

, המוגדרת )(tolowerעל-ידי שימוש בפונקציה הסטנדרטית .ctype.hב-

-כעת אנחנו בטוחים שt1-ו t2.מכילות רק אותיות קטנות נחזיר את הערך שלstrcmp)t1,t2(.

השוואת מחרוזות

Page 10: תכנות מערכות בשפת  C

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? מדוע לא מכפילים את הביטוי שמופיע

?)sizeof)char בביטוי malloc בתוך ה- יש בפונקציה?שגיאהאיזו

Page 11: תכנות מערכות בשפת  C

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;}

השוואת מחרוזות

returnvalue = strcmp(t1,t2) ;

נשים לב שאנחנו מזמנים כאן אתmalloc אבל מבלי לבדוק האם ,

הקצאת הזיכרון הצליחה )אולי כי אין NULLהפונקציה החזירה

זיכרון פנוי?(. יתרה מכך: המצביעיםt1-ו t2

מצביעים על סוף המחרוזת, ולא על תחילתה. איך ניתן

לפתור את הבעיה?

Page 12: תכנות מערכות בשפת  C

פונקציה נוספת המשווה שתי מחרוזות לפי סדר לקסיקוגרפי היא, שכותרתה: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

Page 13: תכנות מערכות בשפת  C

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;}

השוואת מחרוזות

...הפונקציה לא תעבוד כשורהמה חסר?

גם כאן צריך היה לוודא שהקצאת הזיכרון הצליחה...

Page 14: תכנות מערכות בשפת  C

-בstring.h:מוגדרת הפונקציה התקנית char *strpbrk (const char *str1, const char *str2)

-הפונקציה מחזירה מצביע למופע הראשון בstr1 של תו , והגיעה עד str1. אם הפונקציה סרקה את str2מתוך

, מבלי שמצאה אף אחד מהתווים null terminatorל-.NULL, אז היא תחזיר str2שבתוך

חיפוש תווים במחרוזת

Page 15: תכנות מערכות בשפת  C

#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;}

חיפוש תווים במחרוזת?מה יהיה הפלט

Page 16: תכנות מערכות בשפת  C

-פונקציה המוגדרת גם היא ב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[] = "1234567890"; int i = strspn (str,cset); printf ("The length of the number is %d.\n",i); return 0;}

אם התו הראשון שלstr1-אינו שייך ל str2 0, אז הפונקציה תחזיר.

מציאת רישא מותנית

Page 17: תכנות מערכות בשפת  C

-פונקציה הפוכה ל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[] = "1234567890"; int i = strcspn (str,cset); printf ("The first number is at position %d.\n",i+1); return 0;}

-ולכן היא תחזיר את האורך של ’0‘\הפונקציה סורקת גם את ה ,str1 .str1 לא נמצאים ב-str2אם אף אחד מהתווים של

מציאת רישא מותנית