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

Post on 13-Mar-2016

47 Views

Category:

Documents

1 Downloads

Preview:

Click to see full reader

DESCRIPTION

מכללת אורט כפר-סבא. תכנות מערכות בשפת C. מחרוזות. 02.11.14. אורי וולטמן. uri.weltmann@gmail.com. חידה לחימום. נתונות שתי ערימות של קוביות, כשבכל ערימה מספר הקוביות ההתחלתי הוא אקראי. - PowerPoint PPT Presentation

TRANSCRIPT

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

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

אורי וולטמןuri.weltmann@gmail.com

02.11.14

מחרוזות

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

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

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

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

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

מנצח תמיד.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

שוות.

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

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

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

strcmp(“hello”,”hello”) 0

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

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

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

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

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

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

:מוגדרת הפונקציה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(.

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

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 בתוך ה- יש בפונקציה?שגיאהאיזו

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

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

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

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

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

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

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

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

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

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

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

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

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

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

-פונקציה המוגדרת גם היא ב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, אז הפונקציה תחזיר.

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

-פונקציה הפוכה ל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אם אף אחד מהתווים של

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

top related