קבצים קרן כליף. © Keren Kalif 2 ביחידה זו נלמד: מוטיבציה...
-
Upload
rhett-tartt -
Category
Documents
-
view
281 -
download
10
Transcript of קבצים קרן כליף. © Keren Kalif 2 ביחידה זו נלמד: מוטיבציה...
קבצים
כליף קרן
© Keren Kalif
2
: נלמד זו ביחידה קבצים עם לעבודה מוטיבציה : קבצים סוגי
בינארייםטקסט
:) הקבצים ) סוגי שני עבור קבצים על פעולות קובץ פתיחת מקובץ קריאה לקובץ כתיבה קובץ סגירת
: נוספות fseek, ftell, rewind, ferror, fflush, feofפעולות
© Keren Kalif
3
מוטיבציה - קבצים , אנחנו אשר המידע תוכנה כותבים אנחנו כאשר
, מאחר סיומה עם לאיבוד הולך הרצה בכל מכניסים - ה בזיכרון רצה המחשב RAMוהתוכנה של
בזיכרון ההרצות בין המידע את לשמור רוצים היינו: Hard Diskהקבוע ) כדי(
ורצף משמעות בעלת תוכנה ליצור התוכנה בדיקות בעת עלינו להקל
מהמשתמש ולא מראש מוכן מקובץ נתונים קריאת " אחרות תוכניות י ע לשימוש נתונים שמירת
: שונים אופנים בכמה המידע את לשמור ניתןDB) זה ) בקורס יילמד לאקבצים
© Keren Kalif
4
מוטיבציה - קבצים עם כללית עבודה שלה הפלט את לשמור שנרצה תוכנית לנו ותהייה יתכן
לקובץ יהיה שלה שהקלט שנרצה תוכנית לנו ותהייה יתכן
מהמקלדת, ולא מקובץ :דוגמא
מראש ידוע בפורמט מקובץ מספרים אוסף קריאתהמספרים סכום והצגת
" את ושומרת כלשהו ח דו המכינה תוכנית כתיבת , המסך על להצגתו בנוסף בקובץ הדוח
© Keren Kalif
5
קבצים סוגי: טקסט קובץ
ולהבין לקרוא יכולים אנו אותה בשפה כתוב
: בינארי קובץ התוכן את להבין ניתן לא
© Keren Kalif
6
קבצים עם כללי עבודה מבנה* מטיפוס משתנה הוא - FILEקובץ ב stdio.hומוגדר / תוך לכתיבה לקריאה קובץ לפתוח יש העבודה בתחילת
בינארי או טקסט קובץ זהו האם ציון הצליחה פתיחה האם לבדוק יש הקובץ את לסגור יש לבסוף
1. void main()2. {3. FILE* f = fopen(<file name>, <open parameters>);4. if (f == NULL)5. {6. printf("Failed opening the file. Exiting!\n");7. return;8. }9. // here some operation with the file..10. fclose(f);11. }
© Keren Kalif
7
הפתיחה – לסוג פרמטרים קובץ פתיחתFILE* fopen(char* fileName, char* mode);
“ : לקריאה טקסט קובץ ”rפתיחת: לכתיבה טקסט קובץ פתיחת
“ w - ”ידרסו הם בקובץ נתונים ויש במידה“ a .) , לא” – ) קיים אם המידע את דורס לא כלומר קובץ לסוף כותב
! הקובץ לתחילת כתיבה מאפשר: ולכתיבה לקריאה טקסט קובץ פתיחת
“r , יתקבל+” – קיים להיות חייב לא NULLהקובץ אם“w , אותו+” – דורס קיים הקובץ אם“a . , לא+” – חדש קובץ יוצר אחרת לסופו כותב קיים הקובץ אם
! הקובץ לתחילת כתיבה מאפשר נוסיף כבינארי הקובץ את לפתוח . bכדי לפתיחה הפרמטר בסוף
. rb”, “wbלמשל: “ .' טקסט” קובץ היא המחדל ברירת וכו - ב לציין modeניתן : “tהפתיחה . למשל, טקסט קובץ ”wtעבור
© Keren Kalif
8
לכשלון – סיבות קובץ פתיחת
אותו לפתוח שמנסים בלבד לקריאה המוגדר קובץלכתיבה
" " י ע קיים" rפתיחה שאינו קובץ
© Keren Kalif
9
קובץ סגירת
int fclose(FILE* file); ומחזירה לקובץ מצביע לסגור 0מקבלת הצליחה אם
תחזיר, אחרת (EOFהקבוע- ) 1אותו פתוח שאינו קובץ לסגור מנסים כאשר למשל תכשל
int fcloseall(); מספר את ומחזירה שפתחנו הקבצים כל את סוגרת
שסגרה הקבצים
© Keren Kalif
10
טקסט לקובץ כתיבה כמו הן טקסט לקובץ הכתיבה פקודות
: , ש לכך פרט למסך לכתיבה הפקודות עם מתחיל fשמן אליו לקובץ מצביע שהוא נוסף פרמטר מקבלות הן
לכתוב רוצים int fprintf(FILE* , char*, ... ); int fputs(char*, FILE*); int fputc(char, FILE*);
© Keren Kalif
11
דוגמא – ) טקסט לקובץ (1כתיבה1. #include <stdio.h>2. 3. void main()4. {5. FILE* f = fopen("myFile.txt", "w");6. int res;7. if (f == NULL)8. {9. printf("Failed opening the file. Exiting!\n");10. return;11. }12.
13. fprintf(f, "%s %d %lf\n", "KerenK", 28, 99.8);14. fputs("Hello World!", f);15. fputc('A', f);16. 17. fclose(f);18. }
קיים אם הקובץ דריסת
© Keren Kalif
12
דוגמא – ) טקסט לקובץ (2כתיבה1. #include <stdio.h>2. 3. void main()4. {5. FILE* f = fopen("myFile.txt", "w");6. int res;7. if (f == NULL)8. {9. printf("Failed opening the file. Exiting!\n");10. return;11. }12. fputs("Hello World!\n", f);13. fclose(f);14. 15. f = fopen("myFile.txt", "a");16. fputs("And Good Morning!\n", f);17. fclose(f);18. }
לסופו וכתיבה הקובץ פתיחת
© Keren Kalif
13
דוגמא – ) טקסט לקובץ (3כתיבה1. #include <stdio.h>2. 3. void main()4. {5. FILE* f = fopen("myFile.txt", "w");6. int res;7. if (f == NULL)8. {9. printf("Failed opening the file. Exiting!\n");10. return;11. }12. fputs("Hello World!\n", f);13. fclose(f);14. 15. f = fopen("myFile.txt", “w");16. fputs("And Good Morning!\n", f);17. fclose(f);18. }
הקובץ דריסת...הקודם
© Keren Kalif
14
טקסט מקובץ קריאה הפקודות כמו הן טקסט לקובץ הקריאה פקודות
: , ש לכך פרט למסך הקריאה עם מתחיל fשמן רוצים אליו לקובץ מצביע שהוא נוסף פרמטר מקבלות הן
לכתוב
int fscanf(FILE* , char*, ... ); char* fgets(char*, int n, FILE*);
או שקראה המחרוזת את למשל ) NULLמחזירה הצליחה לא אם) נגמר הקובץ
int fgetc(FILE*);הקבוע את או התו של האסקיי ערך את שערכו ) EOFמחזירה
1) נגמר-( ) הקובץ למשל הצליחה לא אם
התווים כמות את גם מקבלותעד. קוראת עד’ n‘\לקריאה -nאו
תווים 1
© Keren Kalif
15
כללי - מקובץ וקריאה שמירה , המידע את לשמור בוחרים אנו לקובץ מידע נשמור כאשר
מסוים בסדר לקובץ הנתונים כתיבת סדר בין התאמה להיות צריכה
מהקובץ הנתונים קריאת לסדר. , : ת: שם הבא בסדר סטודנט על מידע כתבתי אם למשל
, זהה. יהיה הנתונים קריאת סדר גם וגיל ז ,לקובץ שכותב מי בין וידיעה הסכמה להיות צריכה כלומר
בקובץ הנתונים סדר לגבי ממנו שקורא ומי
© Keren Kalif
16
דוגמא – טקסט מקובץ קריאה1. #define SIZE 20
2. void main()
3. {
4. char str[]="Hi", sentence[]="Hello World!", str2[SIZE], sentence2[SIZE];
5. int num1=6, num2=0;
6. float f1=4.5, f2=0;
7. FILE* f = fopen("myFile.txt", "w");
8. // check if open file succeeded..
9.
10. fputs(sentence, f);
11. fprintf(f, "\n%d %f %s\n", num1, f1, str);
12. fclose(f);
13.
14. printf("Before reading from file:\nnum2=%d f2=%f str=|%s| sentence2=|%s|\n", num2, f2, str2, sentence2);
15. f = fopen("myFile.txt", "r");
16. // check if open file succeeded..
17.
18. fgets(sentence2, SIZE, f);
19. fscanf(f, "%d %f %s", &num2, &f2, str2);
20.
21. printf("\nAfter reading from file:\nnum2=%d f2=%f str=|%s| sentence2=|%s|\n", num2, f2, str2, sentence2);
22. fclose(f);
23. }
© Keren Kalif
17
feof int feof (FILE * stream);
ומחזירה פתוח קובץ מקבלת זו הגענו 0פונקציה לא אם - , ו הקובץ לסוף( EOF- )1לסוף והגענו במידה
© Keren Kalif
18
קובץ – העתקת דוגמא1. void main()2. {3. char ch;4. FILE* fSource, *fDest;5. fSource = fopen("example.txt", "r");6. // check if open file succeeded..7. 8. fDest = fopen("exampleCopy.txt", "w");9. // check if open file succeeded..10. 11. ch = fgetc(fSource);12. while (!feof(fSource)) // OR: (ch != EOF)13. {14. fputc(ch, fDest);15. ch = fgetc(fSource);16. }17. 18. fclose(fSource); // returns 0 since close file succeed19. fclose(fDest); // returns 0 since close file succeed 20. }
fcloseall(); // returns 2 since closed 2 files
© Keren Kalif
19
הממוצע וחישוב מקובץ מספרים קריאת1. #include <stdio.h>2. void main()3. {4. FILE* f;5. int num, sum=0, counter=0, rc;6. 7. f = fopen("numbers.txt", "r");8. // check if open succeed...9. 10. rc = fscanf(f, "%d", &num);11. while (rc != EOF) //OR: (!feof(f))12. {13. printf("The read numbers is %d\n", num);14. sum += num;15. counter++;16. rc = fscanf(f, "%d", &num);17. }18. fclose(f);19. printf("The average is %f\n", (float)sum/counter);20. }
© Keren Kalif
20
טקסט לקובץ רשומות וטעינת שמירת
, לכתוב יש טקסט קובץ לתוך רשומה כותבים כאשרשדה- שדה
, לקרוא יש טקסט מקובץ רשומה קוראים כאשרשדה- שדה
© Keren Kalif
21
רשומות וטעינת שמירתדוגמא - טקסט מקובץ
1. #define SIZE 202. struct Person3. {4. char name[SIZE];5. long id;6. float age;7. } typedef person_t;
8. void main()9. {10. person_t p1={"momo", 1111, 23.5}, p2 = {"gogo", 2222, 24.8}, p3, p4;11. FILE* f = fopen("persons.txt", "w");12. fprintf(f, "%s %ld %.2f\n", p1.name, p1.id, p1.age);13. fprintf(f, "%s %ld %.2f\n", p2.name, p2.id, p2.age);14. fclose(f);
15. f = fopen("persons.txt", "r");16. fscanf(f, "%s %ld %f\n", p3.name, &p3.id, &p3.age);17. fscanf(f, "%s %ld %f\n", p4.name, &p4.id, &p4.age);18. fclose(f);
19. printf("p3: name: %s\t id: %ld\t age: %.2f\n", p3.name, p3.id, p3.age);20. printf("p4: name: %s\t id: %ld\t age: %.2f\n", p4.name, p4.id, p4.age);21. }
© Keren Kalif
22
טקסט מקובץ רשומות של מערך וטעינת שמירה
, להיות צריך הראשון השדה לקובץ מערך כותבים כאשר , ידע הקובץ שקורא כדי כותבים שאנו הרשומות מספר
בתוכו יש רשומות כמה
© Keren Kalif
23
רשומות - ) מערך וטעינה (1שמירה1. struct Person
2. {
3. char name[SIZE];
4. long id;
5. float age;
6. } typedef person_t;
7.
8. void main()
9. {
10. FILE* f;
11. person_t* personsSource, *personsDest;
12. int sizeSource, sizeDest, i;
13. printf("How many persons? ");
14. scanf("%d", &sizeSource);
15.
16. // allocating the persons array
17. personsSource = (person_t*)malloc(sizeSource*sizeof(person_t));
18. // reading persons..
19. for (i=0 ; i < sizeSource ; i++)
20. {
21. printf("Enter name, id and age of person #%d: ", i+1);
22. scanf("%s %ld %f", personsSource[i].name, &personsSource[i].id, &personsSource[i].age);
23. }
24. }
© Keren Kalif
24
24. f = fopen("persons.txt", "w");25. fprintf(f, "%d\n", sizeSource); // writing the size to the file26. for (i=0 ; i < sizeSource ; i++) // writing each person to the file27. fprintf(f, "%s %ld %f\n", personsSource[i].name, personsSource[i].id, personsSource[i].age);28. fclose(f);29.
30. free(personsSource); // don’t forget to free the array!!31. 32. f = fopen("persons.txt", "r");33. fscanf(f, "%d\n", &sizeDest); // reading the size from the file34. // allocating the new array35. personsDest = (person_t*)malloc(sizeDest*sizeof(person_t));36. // reading each person from the file37. for (i=0 ; i < sizeDest ; i++)38. fscanf(f, "%s %ld %f\n", personsDest[i].name, &personsDest[i].id, &personsDest[i].age);39. fclose(f);40. 41. printf("There are %d persons in the file:\n", sizeDest);42. for (i=0 ; i < sizeDest ; i++)43. printf("Person #%d: Name=%s\t Id=%ld\t Age=%f\n", i+1, 44. personsDest[i].name, personsDest[i].id, personsDest[i].age);45.
46. free(personsDest); // don’t forget to free the array!!47. }
© Keren Kalif
25
בינארי לקובץ כתיבה: בינארי לקובץ הכתיבה פקודת
int fwrite(const void * ptr, // address of variable to write
int size, // size of type
int count, // number of elements
FILE * stream (; // pointer to the file
שכתבה האיברים כמות את מחזירה מידע של בלוק לכתוב ניתן בינארי לקובץ כותבים כאשר
:בודדת כתיבה בפעולת רשומה או מערך למשל! לקובץ פוינטרים מכתיבת להיזהר יש
© Keren Kalif
26
בינארי מקובץ קריאה: בינארי מקובץ הקריאה פקודת
int fread(void* ptr, // address of variable to read into
int size, // size of type
int count, // number of elements
FILE* stream (; // pointer to the file
שקראה האיברים כמות את מחזירה מידע של בלוק לקרוא ניתן בינארי מקובץ קוראים כאשר
:בודדת קריאה בפעולת רשומה או מערך למשל
© Keren Kalif
27
דוגמא - בינארי מקובץ רשומות וטעינת שמירת1. #define SIZE 202. struct Person3. {4. char name[SIZE];5. long id;6. float age;7. } typedef person_t;8. 9. void main()10. {11. person_t p1={"momo", 1111, 23.5}, p2 = {"gogo", 2222, 24.8}, p3, p4;12. FILE* f = fopen("persons.bin", "wb");13. fwrite(&p1, sizeof(person_t), 1, f);14. fwrite(&p2, sizeof(person_t), 1, f);15. fclose(f);16. 17. f = fopen("persons.bin", "rb");18. fread(&p3, sizeof(person_t), 1, f);19. fread(&p4, sizeof(person_t), 1, f);20. fclose(f);21. 22. printf("p3: name: %s\t id: %ld\t age: %.2f\n", p3.name, p3.id, p3.age);23. printf("p4: name: %s\t id: %ld\t age: %.2f\n", p4.name, p4.id, p4.age);24. }
אחת בפעולה רשומה ולכתוב לקרוא !ניתן
© Keren Kalif
28
רשומות מערך וטעינה שמירהבינארי ) (1מקובץ
1. #define SIZE 20
2. struct Person
3. {
4. char name[SIZE];
5. long id;
6. float age;
7. } typedef person_t;
8.
9. void main()
10. {
11. FILE* f;
12. person_t* personsSource, *personsDest;
13. int sizeSource, sizeDest, i;
14. printf("How many persons? ");
15. scanf("%d", &sizeSource);
16.
17. // allocating the persons array
18. personsSource = (person_t*)malloc(sizeSource*sizeof(person_t));
19. for (i=0 ; i < sizeSource ; i++) // reading persons..
20. {
21. printf("Enter name, id and age of person #%d: ", i+1);
22. scanf("%s %ld %f", personsSource[i].name,
23. &personsSource[i].id, &personsSource[i].age);
24. }
25. }
© Keren Kalif
29
25. f = fopen("persons.bin", "wb");26. fwrite(&sizeSource, sizeof(int), 1, f); // writing the size to the file27. // writing all persons to the file28. fwrite(personsSource, sizeof(person_t), sizeSource, f);29. fclose(f);30. free(personsSource); // don’t forget to free the array!!31. 32. f = fopen("persons.bin", "rb");33. // reading the size from the file34. fread(&sizeDest, sizeof(int), 1, f);35. // allocating the new array36. personsDest = (person_t*)malloc(sizeDest*sizeof(person_t));37. // reading all persons from the file38. fread(personsDest, sizeof(person_t), sizeDest, f);39. fclose(f);40. 41. printf("There are %d persons in the file:\n", sizeDest);42. for (i=0 ; i < sizeDest ; i++)43. printf("Person #%d: Name=%s\t Id=%ld\t Age=%f\n", 44. i+1, personsDest[i].name, personsDest[i].id, personsDest[i].age);45.
46. // don’t forget to free the array!!47. free(personsDest);48. }
© Keren Kalif
30
מצביעים המכילות רשומות כתיבת , אין שכן קובץ לתוך מצביעים לכתוב לא לב לשים יש
ערכים יהיו תרוץ שהתוכנית הבאה שבפעם הבטחהשומרים שאנו הנוכחיות בכתובות
,לרשום להקפיד יש כתובת שהוא משתנה יש כאשר לכןלקובץ ערכו את
: לב " נשים י ע רשומה לרשום של בשיטה להשתמש נוכל לאfwrite- שדה, שדה לקובץ הרשומה את לכתוב חייבים נהיה אלא
, כמות" את נוסף כשדה נרשום למערך הוא המצביע אם כ בד " ( " , עבור ל כנ איבריו את כ אח ורק במערך האלמנטים
מחרוזת(.
© Keren Kalif
31
וטעינה – שמירה דוגמאמצביעים עם רשומה של
1. #include <stdio.h>2. #include <string.h>3. #include <stdlib.h>
4. struct Student5. {6. char* name;7. float average;8. } typedef student_t;
9. void main()10. {11. student_t stud1 = {"yoyo", 91.8}, stud2;12. FILE* f = fopen("students.bin", "wb");13. int len1, len2;14. // check open succeed...15.
16. len1 = strlen(stud1.name)+1;17. fwrite(&len1, sizeof(int), 1, f);18. fwrite(stud1.name, sizeof(char), len1, f);19. fwrite(&stud1.average, sizeof(float), 1, f);20. fclose(f);21. 22. f = fopen("students.bin", "rb");23. // check open succeed...24. 25. fread(&len2, sizeof(int), 1, f);26. stud2.name = (char*)malloc(len2*sizeof(char));27. fread(stud2.name, sizeof(char), len2, f);28. fread(&stud2.average, sizeof(float), 1, f);29. fclose(f);30. printf("stud2: name=%s, average=%.2f\n", 31. stud2.name, stud2.average);32. free(stud2.name);33. }
© Keren Kalif
32
fseekפקודה משדותיו חלק לקרוא בלי בקובץ לטייל מאפשר
int fseek(FILE* f, // the file
long int offset, // how much
int origin (; // from where
origin: הבאים מהערכים אחד יקבלSEEK_SET – הקובץ מתחילת לזוזSEEK_END – הקובץ לסוף לזוזSEEK_CUR – הנוכחי מהמיקום לזוז
תחזיר כמתבקש 0הפונקציה לזוז הצליחה אם: כללי בהן לידע הפעלה מערכות טוב fseekיש עובדת לא
טקסט קבצי על
© Keren Kalif
33
fseek - דוגמא1. #include <stdio.h>2. 3. int main ()4. {5. FILE * f;6. f = fopen("myfile.txt" , "w");7. // check if open succeed8. 9. fputs("This is an apple" , f);10. fseek (f , 9 , SEEK_SET);11. fputs(" sam" , f);12. fclose(f);13. }
© Keren Kalif
34
fseek – – טוב הכי החבר דוגמא1. #define MAX_LEN 20
2. typedef struct Friend3. }4. char name[MAX_LEN];5. int numOfPresentsBoughtMe;6. } Friend;7. 8. void sortFriendByPresents(Friend friends[], int size)9. }10. Friend temp;11. int i, j;12.
13. for (i=0 ; i < size ; i++)14. }15. for (j=i+1 ; j < size ; j++)16. }17. if (friends[i].numOfPresentsBoughtMe > friends[j].numOfPresentsBoughtMe)18. }19. temp = friends[i];20. friends[i] = friends[j];21. friends[j] = temp;22. { 23. }24. {25. {
© Keren Kalif
35
fseek( – – טוב הכי החבר (2דוגמא1. void main()2. }3. FILE* f;4. Friend bestFriend;5. Friend myFriends[] = { {"momo", 5}, {"gogo", 2}, {"yoyo", 7} };6. int numOfFriends = sizeof(myFriends) / sizeof(myFriends[0]);7. 8. sortFriendByPresents(myFriends, numOfFriends);9. 10. f = fopen("myFriends.bin", "wb"); // check open file succeed...11. fwrite(&numOfFriends, sizeof(int), 1, f);12. fwrite(myFriends, sizeof(Friend), numOfFriends, f);13. fclose(f);14. numOfFriends = 0; // just reset to see correct value is read from file..15. // get the friend that bought me most presents16. f = fopen("myFriends.bin", "rb"); // check open file succeed...17. fread(&numOfFriends, sizeof(int), 1, f);18. fseek(f, sizeof(Friend)*(numOfFriends-1), SEEK_CUR);19. //OR: fseek(f, sizeof(Friend)*-1, SEEK_END);20. fread(&bestFriend, sizeof(Friend), 1, f);21. fclose(f);22. printf("The friend who bought me most presents: %s\n", bestFriend.name);23. {
© Keren Kalif
36
ftellהפקודה הקובץ מתחילת הסמן מרחק את מחזירה
long ftell (FILE * f); :קובץ של גודל קריאת .1דוגמא #include <stdio.h>
2. 3. int main ()4. {5. FILE* f;6. long size;7. 8. f = fopen ("myFile.txt", "r");9. // check if open succeed10. 11. fseek (f, 0, SEEK_END);12. size = ftell(f);13. fclose (f);14. printf ("Size of myfile.txt: %ld bytes.\n",size);15. }
© Keren Kalif
37
rewindהפקודה : הקובץ לתחילת הסמן את ;void rewind(FILE* f)מחזירה - ה: כל וכתיבת קריאת .ABC 1דוגמא int main ()
2. {3. int n;4. FILE *f;5. char buffer [27];6.
7. f = fopen ("allLetters.txt","w+");8. // check if open succeed9. 10. for ( n='A' ; n<='Z' ; n++)11. fputc ( n, f);12. rewind (f);13. fscanf(f, "%s", buffer);14. fclose (f);15. buffer[26]='\0';16. puts (buffer);17. }
© Keren Kalif
38
fflushהפקודה int fflush(FILE* f)
- ה את . bufferמרוקנת את שמנקים כמו בדיוק הקובץ של" bufferה- י ע אם 0מחזירה. fflsh(stdin)מהמקלדת
הצליחה.
int fflush() - ה את - bufferמרוקנת ה' כל של הפתוחים streamים
, '(. stdinקבצים) מחזירה .0וכד הצליחה אם
© Keren Kalif
39
ferrorהפקודה מחזירה זו הקובץ 0פקודה על שבוצעו והפעולות במידה
תקינות :בלבד לקריאה שנפתח לקובץ לכתוב ננסה כאשר דוגמא
1. void main()2. {3. FILE* f = fopen("myfile.txt","r");4. if (f == NULL) 5. {6. printf("Error opening file\n");7. return;8. }9.
10. fputc('x', f);11. if (ferror(f))12. printf ("Error Writing to myfile.txt\n");13. fclose(f);14. }
© Keren Kalif
40
במכללה: וסטודנטים קורסים ניהול דוגמא: לתוכנית דגשים
בקבועים שימוש קלט ולקבלת להדפסה יעודיות פונקציותמודולריות לקבצים חלוקה , עבור ספציפית לוגיקה עבור פונקציה יצירת
עתידית תחזוקה :למשלgetDepartmentCodeFromCourseCode
01_ files- final example.zip
© Keren Kalif
41
קובץ אינדקסים - מוטיבציה בהינתן קובץ טקסט עם שורות (ניתן להניח שאורך כל
תווים, אבל לא בהכרח) נרצה 255שורה הוא מקסימום לקרוא תו ספציפי בשורה מסוימת
נקרא שורה-שורה עד השורה המבוקשת, ובתוכה הפתרון :נזוז למיקום הרצוי
בשורה 7: בהינתן הקובץ הבא, נרצה להגיע לתו ה- דוגמא 4
© Keren Kalif
42
הקוד
1. void main()2. {3. int line, col, i;4. char text[256], ch;5. FILE* f = fopen("test.txt", "r"); 6. 7. printf("Enter line and col --> ");8. scanf("%d%d", &line, &col);9. 10. for (i=1 ; i < line ; i++)11. fgets(text, 256, f);12. 13. fseek(f, col-1, SEEK_CUR);14. ch = fgetc(f); 15. printf("The char is '%c'\n", ch);16. 17. fclose(f);18. }
דילוג על השורות הראשונות.
לא ניתן לדלג באמצעות fseek כי אורך השורות
כאשר הסמן נמצא בתחילת שונה.השורה המבוקשת, נקפוץ
ישירות למיקום התו אותו רוצים לקרוא.
פעולת הקריאה מקובץ היא פעולה יקרה ולכן נרצה מנגנון אחר שיחסוך זאת.
כלומר, מנגנון שונה להגעה ישירה לשורה המבוקשת.
© Keren Kalif
43
קובץ אינדקסים - בפתרון כאשר רוצים לבצע קריאות רבות ונקודתיות מקובץ בעל אורך
שורות שונה שאינו משתנה, נשתמש במנגנון הנקרא "קובץ אינדקסים"
-קובץ זה יכיל מספרים, כאשר המספר הi הוא מיקום התו הראשון בקובץiבשורה ה-
:דוגמא
שימושים: למשל עבור ספר טלפונים (נתוניו קבועים), נרצה לקבלנתונים של רשומה אחת
כל שינוי בקובץ המקורי יגרור שינוי בקובץ האינדקס
© Keren Kalif
44
יצירת קובץ אינדקס
קובץ האינדקס חייב להיות בינארי כדי intשבקריאה נוכל לדלג כל פעם על
שלם
פתיחת קובץ הטקסט לקריאה, וקובץ האינדקס
בינארי לכתיבה
נמצא את כמות התווים בקובץ הטקסט
נמצא את מיקום הסמן בתחילת כל שורה, ונכתוב ערך זה לקובץ
האינדקסים
void main(int argc, char* argv[]){ char indexFileName[128], line[256]; FILE *textFile, *indexFile; int currentIndex, numOfChars;
createIndexFileName(argv[1], indexFileName); textFile = fopen(argv[1], "r"); indexFile = fopen(indexFileName, "wb");
fseek(textFile, 0, SEEK_END); numOfChars = ftell(textFile); fseek(textFile, 0, SEEK_SET); currentIndex = 0; while (currentIndex < numOfChars) { fwrite(¤tIndex, sizeof(int), 1, indexFile); fgets(line, 256, textFile); currentIndex = ftell(textFile); }
fclose(textFile); fclose(indexFile);}
© Keren Kalif
45
יצירת שם קובץ האינדקס:פונקציה זו יוצרת את שם קובץ האינדקס כך
עבור קובץ> file name>.txt> :שם קובץ האינדקס יהיהfile name>_index.binעבור דוגמא :test.txt שם ובץ האינדקס יהיה test_index.bin
void createIndexFileName(const char* origName, char indexName[]){
strcpy(indexName, origName);strtok(indexName, ".");strcat(indexName, "_index.bin");
}
© Keren Kalif
46
void main(int argc, char* argv[]){ FILE *textFile, *indexFile; int col, row, lineStartIndex; char ch;
textFile = fopen(argv[1], "r"); indexFile = fopen(argv[2], "rb");
printf("Enter row and col --> "); scanf("%d%d", &row, &col);
fseek(indexFile, (row-1)*sizeof(int), SEEK_SET); fread(&lineStartIndex, sizeof(int), 1, indexFile); fseek(textFile, lineStartIndex+col-1, SEEK_SET); fscanf(textFile, "%c", &ch);
printf("The char is %c\n", ch);
fclose(textFile); fclose(indexFile);}
שימוש בקובץ אינדקס
פתיחת קובץ הטקסט וקובץ הבינארי לקריאההאינדקס
קריאה מקובץ האינדקס את מיקום תחילת השורה
הזזת הסמן בקובץ הטקסט למיקום המבוקש
וקריאה
© Keren Kalif
47
, , : סיביות קבצים סיכום variadicדוגמאתfunctions
של כלשהי וכמות בינארי קובץ של שם המקבלת פונקציה כתובהוא, שסכומם שנתון יהיה ) 8מספרים האחרון ליצוג, 0המספר
) הפרמטרים סיום . מספר המייצגות סיביות כמות מייצג מספר כל המספרים את ולהציג הבינארי הקובץ את לקרוא יש
. בתוכו המקודדים ,המספרים עבור שנקראו 4,1,3למשל הבאים והבתים
(:abcמהזכרון )0 1 1 0 0 0 0 1 0 1 1 0 0 0 1 0 0 1 1 0 0 0 1 1
: הבאים המספרים למסך יודפסו
© Keren Kalif
48
1. #include <stdio.h>
2. #include <stdlib.h>
3. #include <string.h>
4. #include <stdarg.h>
5.
6. unsigned char createMask(int high, int low);
7. int getSubNumber(char ch, unsigned char mask, int high, int low);
8. void readNumbers(const char* fileName, ...);
9.
10. void main()
11. {
12. char str[] = "abc"; // a: 01100001 b: 01100010 c: 01100011
13. FILE* f = fopen("test.bin", "wb");
14. fwrite(str, sizeof(char), strlen(str), f);
15. fclose(f);
16.
17. readNumbers("test.bin", 4, 1, 3, 0);
18. {
© Keren Kalif
49
/* This function receives higher and lower bounds of bit indexes, and creates a mask with 1 in this range, and 0 in all other places.
I.E: high=5, low=3, the mask char would be: 00111000*/19. unsigned char createMask(int high, int low)20. {21. return ( 1 << ( high + 1 ) ) - ( 1 << low );22. {
6 >> 1 1000000 643>> 1 1000 8
56=64-8 00111000
מוזמנים לקרוא את ההסבר לפונקציה זו בדפים שבאתר!
© Keren Kalif
50
28. void readNumbers(const char* fileName, ...)29. {30. FILE* f;31. va_list numbers;32. int highBit, lowBit, i, numOfNumbers=0, arr[8];33. unsigned char ch;34. unsigned char* masks;35. 36. f = fopen(fileName, "rb");37. if (f == NULL)38. exit(1); 39. 40. // get the numbers41. va_start(numbers, fileName);42. arr[numOfNumbers] = va_arg(numbers, int);43. while (arr[numOfNumbers] != 0)44. }45. numOfNumbers++;46. arr[numOfNumbers] = va_arg(numbers, int);47. {48. 49. // allocate the masks array50. masks = (char*)malloc(numOfNumbers*sizeof(unsigned char));
© Keren Kalif
51
51. // creates the masks52. highBit=7;53. for (i=0 ; i < numOfNumbers ; i++)54. }55. lowBit = highBit - arr[i] + 1;56. masks[i] = createMask(highBit, lowBit);57. highBit = lowBit - 1;58. }59. while (1) 60. }61. fread(&ch, sizeof(char), 1, f);62. if (feof(f)) break;63. printf("From char '%c' --> ", ch);64. highBit=7;65. for (i=0 ; i < numOfNumbers ; i++)66. {67. lowBit = highBit - arr[i] + 1;68. printf("%d ", ((ch & masks[i]) >> lowBit));69. highBit = lowBit - 1;70. }71. printf("\n");72. {73. fclose(f);74. free(masks);75. {
© Keren Kalif
52
תמונה: קידוד המכיל בינארי קובץ יצירת דוגמא. תמונה של יצוג המכיל בינארי קובץ לייצר יש - מ מורכבת , M*Nתמונה צבע יש פיקסל שלכל כך פיקסלים
(.16יש) אפשריים צבעים " הפיקסלים כל את כ ואח התמונה מימדי את לקובץ לכתוב יש
.' , : וכו השניה הראשונה מהשורה הפיקסלים הסדר לפי
- , ב להסתפק ניתן צבע כל לשמור מנת סיביות 4על
בכלbyte עבור נתונים לשמור פיקסלים 2ניתן
עם - M*Nתמונה ב תשמר בתים N*M/2 + 2פיקסלים
התמונה 2 מימדי לשמירת בהתחלה בתים
08_ bits examples.zip
© Keren Kalif
53
בתמונה: 2דוגמא מסוים לפיקסל צבע שינוי
קאורדינטת לתת , x,yיש את לעדכן ישירה ובגישה וצבעהפיקסל.
המבוקשת הקאורדינטה עבור הצבע האם לב לשים יש - ה של השמאלי בצד אא הימני בצד הוא byteנמצא בו
נשמר
© Keren Kalif
54
: למדנו זו ביחידה
מוטיבציה : סיביות עם לעבודה אופרטורים
&| ^ ~ >> <<