פעולות עם קבצים-המשך
דוגמא:
אחד התלמידים בכיתה שכפל את קובץ הציונים.כעת יש על הדיסק שני קבצים.
התלמיד מעוניין לראות אם אחד הקבצים לא שונה בזמן האחרון.התלמיד מניח כי אין הוספה או גריעה של ציונים בקבצים (אלא,שינוי בלבד).
את שמות הקבצים יש לקלוט דרך מקלדת.
ברצוננו לפתור את הבעיה ולרשום תוכנית שתבצע את ההשוואה.יש להדפיס הודאות מתאימות בהתאם לתוצאות ההשוואה(היה שינוי או לא).
בקבצים אלו רשום מספר תלמיד ולאחריו ציון במבנה הבא:
|
ציון |
מ'ס תלמיד |
* * * * |
ציון |
מ'ס תלמיד |
תו המציין את סוף הקובץ תחילת הקובץ
פיתרון:
לצורך קליטת שמות הקבצים מהתלמיד המשתמש בתוכנה,ננצל את העובדה שהקובץ על הדיסקט המוגדר בהוראה assign עם גרש ימני ושמאלי(מחרוזת)
אם זו מחרוזת אזי אפשר להשתמש במשתנה מחרוזתי.
program COMPERE_FILES; var ST:string[12]; (*המחרוזת שאליה יוצבו שמות הקבצים בדיסק*) F1,F2:text; (*באופן שרירותי,שמות הקבצים בתוכנית*) RESULT:Boolean; (*דגל המציין אם הקבצים שווים או לא*) NUMBER1.NUMBER2:integer; (*מספרי התלמיד בשני הקבצים*) MARK1,MARK2:real; (*הציונים בשני הקבצים*) procedure INIT; {תת תוכנית לקביעת ערכים התחלתיים ופתיחת הקבצים} begin write('Enter name of first file: '); readln(ST); (*שם הקובץ הראשון יוצב לתוך המחרוזת*) assign(F1,ST); (*הקובץ בתוכנית מקושר לקובץ על הדיסק*) write('Enter name of second file: '); readln(ST); assign(F2,ST); reset(F1); reset(F2); (*הכנת קבצים לקריאה*) end;
procedure COMPARE; {תת תוכנית לבדיקת שיווין קבצים } begin RESULT:=true; (*נניח בהתחלה שהקבצים שווים*) (*אם אחד מהקבצים הסתיים,יש לצאת מהלולאה*) while ( (not (eof(F1))) and (not (eof(F2))) and RESULT) do begin readln(F1,NUMBER1); readln(F1,MARK1); readln(F1,NUMBER2); readln(F1,MARK2); if (NUMBER1<>NUMBER2 or MARK1<>MARK2) then RESULT:=false; end; (*לאחר הסיום של הבדיקה יש לסגור את הקבצים*) close(F1); close(F2); end;
procedure MESSAGE_OUT; {תת תוכנית המדפיסה את תוצאות ההשוואה} begin if RESULT then writeln ('The files are equal!') end;
(**********התוכנית הראשית********)
begin INIT; (*בצע אתחול*) COMPARE; (*בצע השוואה*) MESSAGE_OUT; (*הדפס תוצאת השוואה*) end.
|
להורדת הדוגמא לחץ כאן
נביט פנימה לתוך הקובץ כדי להבין את אופן שמירת הנתונים ע"י הוראת write ו- wrietln.
כאשר מבוצעת ההוראה ;(wrietln(F,I כלומר,כתוב לקובץ F את תוכן משתנה I ,נכתב גם תו נסתר המציין סיום שורה.הרישום בקובץ כאילו קופץ לשורה חדשה (על הצג זה נעשה ממש).
לדוגמא,מבוצעות ההוראות הבאות (שם הקובץ F ,מסוג text ):
writeln (F,'a'); writeln (F,'b'); writeln (F,'c'); |
אזי הנתונים ישמרו לקובץ כך:
כאשר נשתמש בהוראת write ולא ב- writeln לא יופיע התו המציין סיום שורה.
אחת התקלות הנפוצות היא השימוש בהוראת read כאשר נרשם לקובץ wrietln. גם השימוש בהוראת readln במקום שנרשם לקובץ write תגרום לקריאה לא נכונה של הנתונים.
לדוגמא,נתון הקובץ F מסוג text ,שאליו נרשמו הנתונים הבאים ע"י ההוראה write.
...a b c
וקיימת פקודה הקוראת מהקובץ: ;( readln(F,C,I.אזי,לאחר הוראה זו המצביע על המקום שממנו נקרא בפעם הבאה יעמוד על המקום הבא שלאחר הסימן המציין קפיצת שורה (כאן אין מקום כזה).ברור, כי קריאת הנתונים בהמשך לא תהיה נכונה.
קריאת נתונים מקובץ צריכה להתאים לאופן בו נרשמו נתונים לקובץ!!! |
גם בשימוש מחרוזות ושמירתן לקובץ, לעיתים יש צורך להשתמש ב-
writeln ו-readln.
לדוגמא,אם מוגדרת מחרוזת באורך 10 תווים ונבצע קריאה של משתנה מחרוזתי מהקובץ,המשתנההמחרוזתי יקלוט 10 תווים אפילו אם המחרוזת שנכתבה לקובץ היא באורך דינאמי של 3 תווים.לכן אם נרשום את המחרוזת ע"י ההוראה writeln ונקרא את המחרוזת ע"י readln, למחרוזת יקרא האורך הדינאמי ולא יותר.כך נקבל במשתנה מחרוזתי את הערך שנכתב לקובץ.
כלומר,כאשר משתמשים בקובץ אליו שומרים נתונים שונים כולל מחרוזת,רצוי להשתמש בהוראות writeln ו- readln.
דוגמא:
כתוב תוכנית הקולטת שמות תלמידים בכיתה,וציוני בחינה.התוכנית שומרת את הנתונים לקובץ בשם MARK.DAT על הדיסק.בכיתה 40 תלמידים.
בסיום הכתיבה לקובץ,התוכנית תקרא מהקובץ את שמות התלמידים וציונם ותדפיס שוב על הצג.
פיתרון:
program SAVE_NAME_AND_MARKS; {תוכנית השומרת שמות תלמידים וציונם לקובץ} var I:integer; (*מונה הלולאה*) F:text; (*הקובץ המוגדר בתוכנית*) NAME:string[20]; (*מחרוזת שם התלמיד*) MARKS:real; (*ציון התלמיד*) begin assign (F,'MARK.DAT'); rewrite(F); for I:=1 to 40 do begin write('הקש שם תלמיד'); readln(NAME); writeln(F,NAME); (*text כל נתון נשמר בשורה נפרדת לקובץ מסוג *) writeln(F,MARKS); end; reset(F); for I:=1 to 40 do begin readln(F,NAME); (*המחרוזת הדינאמית נקראת*) readln(F,MARKS); writeln(NAME,' ',MARKS); (*על הצג*) end; close(F); end. |
להורדת הדוגמא לחץ כאן