Presentation is loading. Please wait.

Presentation is loading. Please wait.

תכנות מערכות בשפת C עבודה עם קבצים מכללת אורט כפר-סבא אורי וולטמן

Similar presentations


Presentation on theme: "תכנות מערכות בשפת C עבודה עם קבצים מכללת אורט כפר-סבא אורי וולטמן"— Presentation transcript:

1 תכנות מערכות בשפת C עבודה עם קבצים מכללת אורט כפר-סבא אורי וולטמן
אורי וולטמן

2 חידה לחימום יש פתק שעליו כתובים 23 משפטים.
המשפט הראשון אומר: "על פתק זה כתוב משפט שקרי אחד בלבד". המשפט השני אומר: "על פתק זה כתובים שני משפטים שקריים בלבד". המשפט השלישי: "על פתק זה כתובים שלושה משפטים שקריים בלבד". וכך הלאה, עד המשפט ה-23, שאומר: "על פתק זה כתובים משפטים שקריים בלבד". השאלה היא: כמה משפטים נכונים כתובים על הפתק, אם בכלל? ומיהם, אם הם קיימים?

3 פתיחת קובץ כאשר רוצים להתחיל לעבוד עם קובץ, צריך להצהיר על משתנה מסוג מצביע לקובץ. ההצהרה נעשית, לדוגמא, באופן הבא: FILE *filep; שורה זו מגדירה את המשתנה filep להיות מצביע לקובץ. טיפוס נתונים זה מוגדר ביחידת הספרייה stdio.h. מרגע שהגדרנו משתנה מטיפוס מצביע לקובץ, נוכל לפתוח קובץ לעבודה על-ידי הפונקציה fopen, המוגדרת גם היא ב-stdio.h. פונקציה זו מקבלת כפרמטר מחרוזת המתארת שם של קובץ, ומחרוזת שנייה המגדירה את הצורה שבה פותחים את הקובץ, והיא מחזירה ערך מטיפוס FILE* שאותו נשים במשתנה שהגדרנו. filep = fopen(“students.dat”, “r+b”); ב-stdio.h מוגדר קבוע בשם FOPEN_MAX הקובע מהו המספר המקסימלי של קבצים שיכולים להיות פתוחים בו זמנית.

4 פתיחת קובץ הפרמטר השני של fopen מציין את הצורה בה אנו בוחרים לפתוח את הקובץ. אילו ערכים יכולים להופיע שם? r – פתיחת קובץ לקריאה (read) בלבד. חובה שיהיה קיים קובץ בשם זה. w – יצירת קובץ חדש לכתיבה (write). אם כבר קיים קובץ בשם זה – הוא יימחק. a – פתיחת קובץ להוספה (append). המצביע עומד על סוף הקובץ, ורק שם מותר לכתוב נתונים חדשים. פעולות קריאה אסורות. r+ - פתיחת קובץ לעדכון (מותרת גם קריאה וגם כתיבה). חובה שהקובץ יהיה כבר קיים. w+ - יצירת קובץ חדש לכתיבה ולקריאה. אם כבר קיים קובץ בשם זה – הוא יימחק. a+ - פתיחת קובץ לקריאה ולהוספה. המצביע עומד על סוף הקובץ, ורק שם מותר לכתוב נתונים חדשים. מותר לקרוא נתונים קיימים, אך לא לשנותם.

5 פתיחת קובץ את התכונות של הפרמטרים השונים ניתן לסכם בטבלה הבאה:

6 פתיחת קובץ האות ‘b’ שהופיעה בפרמטר השני בדוגמא שלעיל, מציינת שמדובר בקובץ בינארי (binary file), כלומר – בקובץ המכיל נתונים. לחלופין, יכולנו לרשום את האות ‘t’ כדי לציין שמדובר בקובץ טקסט (text file) המכיל תווי טקסט. ברירת המחדל, אם לא היינו כותבים דבר, היא שזהו קובץ טקסט. עבור קבצי טקסט ישנן פונקציות מיוחדות לקריאה ולכתיבה (של תווים או של מחרוזות), אבל אפשר להשתמש גם בפונקציות הקריאה והכתיבה הרגילות. התו 't' או ‘b’ יכול להופיע הן מימין ל-'+' (אם קיים) והן משמאלו. בכל מקרה, התו הפותח חייב להיות ‘w’, ‘a’ או ‘r’. לדוגמא: הצירופים “wb+” ו-“rt” חוקיים, אבל הצירופים “+rb” ו-"bw" אינם.

7 פתיחת קובץ לאחר הקריאה ל-fopen יש לבדוק האם הפתיחה הצליחה או נכשלה. במידה והפתיחה נכשלה, הפונקציה מחזירה NULL. filep = fopen(“students.dat”,”r+b”); if (filep == NULL) { printf(“Error opening file\n”); } נניח שהקובץ students.dat מורכב כולו מרשומות סטודנט הבנויות כך: struct student { char name[20]; float grades_average; };

8 קריאה מקובץ על קובץ ניתן לבצע מספר פעולות, כאשר הבסיסיות הן קריאה וכתיבה. לקריאה מקובץ נשתמש בפונקציה fread המוגדרת ב-stdio.h. במקרה של קובץ הבנוי מרשומות, כשנקרא מקובץ – בדרך-כלל נקרא רשומה אחת. את הפונקציה fread מזמנים באופן הבא: fread(<יעד>,<גודל>,<כמות>,<מקור>); כלומר – קרא נתונים מתוך הקובץ שכתובתו מופיע ב-'מקור'. קרא משם 'כמות' איברים, שגודל כל אחד מהם הוא 'גודל' בתים. את הנתונים שקראת, אחסן במשתנה שכתובתו מופיעה ב-'יעד'. לדוגמא: struct student talmid; ... fread(&talmid,sizeof(struct student),1,filep); הוראה זו תקרא מהקובץ ש-filep מצביע אליו, רשומה אחת בגודל sizeof(struct student) בתים, לתוך talmid.

9 קריאה מקובץ דוגמא נוספת: לו הקובץ students.dat היה נראה כך, מה
if ((fp = fopen(“students.dat”,”r+b”)) == NULL) { printf(“Error opening file\n”); return 1; } fread(&talmid,sizeof(struct student),1,fp); printf(“%d\n”,talmid.age); printf(“%s\n”,talmid.name); לו הקובץ students.dat היה נראה כך, מה היה הפלט של קטע תכנית זה?

10 קריאה מקובץ הפונקציה fread מחזירה ערך שניתן להשתמש בו על מנת לבדוק אם היא פעלה כהלכה – בסיום פעולתה היא מחזירה את מס' האיברים שהיא קראה בפועל. אפשר לבדוק את הערך המוחזר, ולפיו לדעת האם קריאת הקובץ התנהלה בהצלחה. לדוגמא: struct student talmidim[4]; /* הגדרת מערך של 4 סטודנטים */ int numbers; ... numbers = fread(talmidim,sizeof(struct student),4,fp); if (numbers!=4) printf(“Error!\n”);

11 כתיבה לקובץ בנוסף לאפשרות לקרוא מקבצים, ניתן גם לבצע כתיבה אל תוך קובץ (בהנחה שפתחנו את הקובץ באופן המאפשר גם כתיבה) וזאת בעזרת הפקודה fwrite, המוגדרת גם היא ב-stdio.h. המבנה של הפונקציה fwrite הוא: fwrite(<מקור>,<גודל>,<כמות>,<יעד>); נניח שנשתמש בקובץ מהדוגמא הקודמת, ונריץ את קטע התכנית הבא: fp = fopen(“students.dat”,”r+b”) printf(“הקש שם”); gets(std.name); printf(“הקש גיל”); scanf(“%d”,&std.age); fwrite(&std,sizeof(struct student),1,fp); לו הקלט היה “David” ו-20, כיצד היה נראה הקובץ לאחר ביצוע קטע הקוד? וכיצד היה נראה הקובץ לו היינו פותחים אותו עם המאפיין "a+b"? וכיצד היה נראה הקובץ לו היינו פותחים אותו עם המאפיין "wb"? "rb"? "w+b"?

12 חישוב היסט בקובץ הפונקציה ftell, המוגדרת ב-stdio.h, מקבלת מצביע לקובץ ומחזירה ערך מטיפוס long, המציין את מס' הבתים מהנקודה בה היה המצביע אחרי שהקובץ נפתח (בד"כ, מדובר בתחילת הקובץ) ועד לנקודה בה נמצא המצביע כעת. לדוגמא: f = fopen(“students.dat”,”r+b”); num = ftell(f); printf (“%ld”, num); הפלט יהיה אפס, מכיוון שהמצביע ממוקם בתחילת הקובץ (ההיסט מתחילת הקובץ הוא אפס בתים).

13 חישוב היסט בקובץ אם, נניח, גודלה של רשומה בקובץ הוא 12 בתים, אז מה יהיה הפלט של קטע הקוד הבא? f = fopen(“students.dat”,”r+b”); fread(&talmid,sizeof(struct student),1,f); printf (“%ld”, ftell(f)); fwrite(&talmid,sizeof(struct student),1,f);

14 תזוזה בקובץ את מיקום המצביע בקובץ אפשר לשנות ישירות באמצעות הפונקציה fseek, המוגדרת ב-stdio.h. מבנה הפונקציה הוא כזה: fseek(<קובץ>,<היסט>,<נקודת מוצא>); 'קובץ' פירושו מצביע לקובץ המסוים שבו רוצים לשנות את מיקום המצביע. ההיסט פירושו מס' הבתים (מס' מסוג long) שיש להסיט את המצביע מנקודת המוצא. ערך זה יכול להיות חיובי או שלילי. ערך חיובי מציין תזוזה של מספר בתים קדימה, וערך שלילי מציין תזוזה של מספר בתים אחורה. נקודת המוצא מסמנת את המקום שממנו נתקדם מס' בתים רצוי. לשדה זה יכולים להיות שלושה ערכים אפשריים: SEEK_CUR – תזוזה מהמיקום הנוכחי. SEEK_END – תזוזה מסוף הקובץ. SEEK_SET – תזוזה מהנקודה בה היה המצביע לאחר פתיחת הקובץ (בד"כ, מדובר בתחילת הקובץ). שלושה קבועים אלה מוגדרים ב-stdio.h.

15 תזוזה בקובץ אם נרצה, למשל, להצביע על הרשומה השלישית בקובץ items.bin, אז נכתוב: fptr = fopen(“items.bin”,”r+b”); fseek(fptr,2*sizeof(struct item),SEEK_SET); לאיפה היה מצביע הסמן אם היינו מחליפים את SEEK_SET ב-SEEK_CUR? אם נרצה להזיז את המצביע לסוף הקובץ אז נכתוב: fseek(fptr,0,SEEK_END); ב-stdio.h מוגדרת פונקציה בשם rewind, המקבלת מצביע לקובץ, ומעבירה אותו אל ראש הקובץ. לדוגמא: שתי ההוראות הבאות שקולות לגמרי - rewind(fptr); fseek(fptr,0,SEEK_SET);

16 תזוזה בקובץ להלן קטע תכנית המחשב את גודלו הנוכחי של קובץ על-ידי קפיצה לסופו ובדיקת מיקום המצביע: long place; FILE *fp = fopen(“data1”,”rb”); if (fp==NULL) { printf(“Error!\n”); return 1; } else { fseek(fp,0,SEEK_END); place = ftell(fp); printf(“the file size is %ld bytes”,place); }

17 מציאת סוף קובץ פונקציה חשובה נוספת היא הפונקציה feof (המוגדרת ב-stdio.h). פונקציה זו מקבלת מצביע לקובץ, ומחזירה ערך שונה מאפס כאשר המצביע ביצע פעולת קריאה מעבר לסוף הקובץ, ואת הערך 0 כאשר עוד לא הגענו לסוף קובץ. FILE *fp = fopen(“data1”,”rb”); if (fp==NULL) { printf(“Error!\n”); } else { fread(&rec,sizeof(struct record),1,fp); while (!feof(fp)) { printf(“%d ”,rec.code); }

18 סגירת קובץ לאחר שמסיימים לעבוד על קובץ חובה לסגור אותו, כדי שמערכת ההפעלה תדע שסיימנו לעבוד עליו ושתוכניות אחרות יכולות לגשת אליו. סגירת הקובץ נעשית בד"כ בסוף התוכנית, אך לא בהכרח, והיא מתבצעת על ידי הפקודה fclose. לדוגמא: FILE *datafile; datafile = fopen(“FILE.EXT”,”at”); ... fclose(datafile); בדוגמא זו התכנית סוגרת את הקובץ datafile לאחר שסיימנו לעבוד עליו. כל פנייה אל הקובץ כשהוא סגור תהיה שגיאה. גם הפונקציה fclose מוגדרת ביחידת הספרייה stdio.h.


Download ppt "תכנות מערכות בשפת C עבודה עם קבצים מכללת אורט כפר-סבא אורי וולטמן"

Similar presentations


Ads by Google