דוא"ל:
תפריט משתמש




שתף |

קורס:"שפת C"

שיעור 4: קלט / פלט 

[ <<< הקודם ] [ תוכן עניינים ] [ הבא >>> ]

מתוך הספר: C - מדריך מקצועי       C - מדריך מקצועי
תוכן עניינים



קלט / פלט של תו בודד

כפי שראינו בפרק 2, "הכרת שפת C", קריאת וכתיבת תו בודד מבוצעת ע"י הפונקציות getchar() ו- putchar().

שתי אלה מוגדרות בספרייה התקנית של C כפונקציות מקרו (באמצעות הקדם מעבד) בקובץ stdio.h.

getchar()

זוהי פקודת הקלט הפשוטה ביותר אשר בעזרתה ניתן לקרוא תו אחד מהקלט הסטנדרטי (בדרך כלל המקלדת). פונקציה זו מחזירה את תו הקלט הבא בכל פעם שהיא נקראת.

לדוגמא, בכדי לקרוא תו מהקלט נבצע:

 
int ch;
ch = getchar();
 

שאלה: מדוע התו מוגדר כ- int ולא כ- char?

תשובה: סוף הקלט מצוין ע"י הקבוע EOF המוגדר בספרייה stdio.h כך:

 
          #define EOF     (-1)
 

בהגעה לסוף הקלט, הפונקציה getchar() מחזירה את EOF. משום כך על הערך המוחזר של הפונקציה להיות מטיפוס שלם, הכולל גם את תחום הערכים השליליים.

לדוגמא, הלולאה הבאה מונה את כלל התווים שנקראו מהקלט:

 
          while (getchar()!=EOF)
                   ++chars_no;
 

שאלה: כיצד מסמנים סוף קובץ קלט ע"י המקלדת?

תשובה: במערכת ההפעלה Windows ע"י Ctrl-Z, וב- Unix ע"י Ctrl-D.

putchar()

זוהי פקודת הפלט הפשוטה ביותר אשר כותבת לפלט הסטנדרטי  ( בדרך כלל המסך ) את התו הנתון לה כפרמטר:

 
          putchar(ch);
 

לדוגמא, ההוראה

 
          putchar('A');
 

תדפיס:

 
A
 


'A' הוא ערך ASCII של התו A, כלומר 65. לכן ניתן להדפיס את התו A גם ע"י ההוראה:

 
          putchar(65);
 

בדומה ל- getchar(), גם putchar() מטפלת בטיפוס int ולא char בכדי לאפשר הדפסת תו סוף קובץ, EOF.

תכנית הדוגמא הבאה קולטת תו מהמשתמש (באמצעות המקלדת) ומדפיסה אותו למסך:

 
#include <stdio.h>
void main ( )
{
          int ch;
          
          ch = getchar();
          putchar(ch);
}
 

קריאת תווי קלט וניתוחם

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

תכנית למניית תווים

התכנית הבאה מונה את מספר תווי הקלט שנקראו ומדפיסה מספר זה:

 
/* file: count_chars.c */
#include <stdio.h>
void main ()
{
          long chars_no=0;
 
          while (getchar()!=EOF)
                   ++chars_no;
          printf("Read %ld chars\n", chars_no);
}
 

אם נריץ את התכנית ונקליד את הקלט הבא:

 
This file is a stream of text chars. It can have all kinds of characters: a, z, 3, *, &amp;, @, &#123; &#125;, ש, ת ; | / ? &gt; _ = +
 


יתקבל הפלט:

 
Read 118 chars
 


הסבר: התכנית קוראת תווים מהקלט - שהוא זרם תוים - עד להגעה לתו מסיים קובץ (EOF):



  • התכנית קוראת את התווים וסופרת אותם ע"י המשתנה chars_no. בהגעה לסוף הקובץ מודפס מספר התווים שנקראו - כלומר גודל קובץ הקלט.
  • המשתנה המונה את התווים chars_no הוא מטיפוס long כדי לאפשר טיפול במספר גדול של תווים.
  • האות l במחרוזת הבקרה "%ld" מציינת ל- printf שהפרמטר הוא מטיפוס long.

תרגול

קרא/י סעיף זה בספר ובצע/י את תר' 1-2 שבעמ' 89.

מניית שורות

הקלט הוא זרם תווים המסתיים בתו מסיים קובץ (EOF). בתוך זרם התווים, נמצא תו מיוחד ('\n') המציין מעבר שורה חדשה:

נכתוב תכנית למניית מספר השורות בקלט.

לספור את השורות פירושו לספור תווי "שורה חדשה" בקלט, כלומר כמה פעמים הופיע התו מסיים השורה ('\n') בזרם הטקסט שבקלט.

אלגוריתם התכנית:

משתנים: c - התו הנקרא הבא ,lines_no - מונה השורות
אתחול:  lines_no  מאותחל ל- 0
כל עוד התו הנקרא, c , אינו תו סוף קובץ
          אם c  תו סוף שורה, הוסף 1 ל- lines_no
הדפס את lines_no

קוד התכנית:

 
/* file: count_lines.c */
#include <stdio.h>
void main ()
{
          int c;
          int lines_no=0;
          while ((c=getchar())!=EOF) 
          {
                   if (c=='\n')
                            ++lines_no;
          }
          printf("Read %d lines\n",lines_no);
}
 

אם נריץ את התכנית ונקליד את הקלט הבא:

 
This is the first line. 
This is the second line. 
This is the third line.
 


יתקבל הפלט:

 
Read 3 lines
 


תרגול

קרא/י סעיף זה בספר ובצע/י את תר' 1-2 שבעמ' 91.

מניית מילים

כדי לספור מילים צריך להגדיר מילה. אנו נגדיר מילה בצורה פשוטה:

    מילה היא סדרת תווים רצופה שלא מכילה בתוכה תו "לבן" מכל סוג שהוא: תו רווח, טאב או תו שורה חדשה.

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

הרעיון: נגדיר משתנה מצב (state) שיציין במהלך קריאת התווים אם אנו בתוך מילה (INSIDE) או מחוץ לה (OUTSIDE).

בכל מעבר ממצב OUTSIDE למצב  INSIDE נקדם את מונה המילים.

האלגוריתם:

משתנים: state - משתנה המצב, c - התו הנקרא מהקלט, words_no - מונה המלים
אתחול: state <-- OUTSIDEwords_no <-- 0
כל עוד התו הנקרא, c , אינו תו סוף קובץ
          אם c הוא תו "לבן"
                           state <-- OUTSIDE
          אחרת, אם state  הוא OUTSIDE
                           state <-- INSIDE
                           הוסף 1 ל- words_no
הדפס את words_no

קוד התכנית והסבר מובאים בעמ'  93. קרא/י סעיף זה בספר ובצע/י את תר' 1-3 שבעמ' 94.

פלט לפי תבנית ע"י printf

פונקצית הספריה printf משמשת להדפסת פלט מורכב: היא כוללת אפשרויות לשילוב טקסט עם ערכי משתנים, רווח, הצמדה ואפשרויות נוספות.

הטכניקה שבה היא פועלת כוללת מחרוזת בקרה ופרמטרים להדפסה:

int printf ("מחרוזת בקרה", <<פרמטר2>, <פרמטר1 ...);

מחרוזת הבקרה מורה ל- printf כיצד והיכן להציב את הפרמטרים בשורת הפלט.

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

 
printf("The %d exam grades are %f and %f", 2, 87.5, 93.4);
 

הפלט:

 
The 2 exam grades are 87.500000 and 93.400000
 

כל מציין פורמט מתחיל בתו האחוזים (%) ואחריו אות המסמנת את טיפוס הפרמטר:

  - מציין הטיפוס הראשון, %d , מציין טיפוס שלם ומתייחס לפרמטר 2
  - מציין הטיפוס השני, %f, מציין טיפוס ממשי ומתייחס לפרמטר 87.5
  - מציין הטיפוס השלישי, %f, מציין טיפוס ממשי ומתייחס לפרמטר 93.4

הטבלה שבעמ' 95 מפרטת את מצייני הטיפוס עפ"י קטגוריות הטיפוסים.

דוגמאות פשוטות:

הוראה

פלט

 
 printf("%c",65);
 

A

 
 printf("I am %d   years old",12);
 

I am 12 years old

 
printf("An apple   costs %f per Kilo",14.44);
 

An apple costs 14.440000 per Kilo

 
printf("%d is %x in   hexa and %o in octal",
            17,17,17);
 
 
17 is 11 in hexa and 21 in octal
 
 
 printf("a\tb\tc");
 

a    b    c   

דוגמאות מורכבות יותר:

הוראה

פלט

 
printf("%s   world", "hello");
 
 
hello world
 
 
printf( "Real = %f %e %E", 23.452, 23.452, 23.452);
 
 
Real = 23.452000 2.345200e+001 2.345200E+001
 
 
int num;
  printf(   "Address=%p", &num);
 
 
Address=006FDD8
 
 
printf("1234567890%n", &chars_no);
  printf("\nChars writen=%d",chars_no);
 
 
1234567890
  Chars writen=10
 

קביעת תצורת הפלט

ריווח

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

 
printf("%f %d %s\n", 45.583f, 5, "hello");
 

תציג למסך:

 
45.583000 5 hello
 


ניתן לקבוע את רוחב השדה בהדפסת פרמטר מסוים ע"י הצבת מספר בין הסימן % למציין הטיפוס. לדוגמא, את הנתונים מההדפסה הקודמת נדפיס בשדה ברוחב 8 תווים:

 
printf("%8f%8d%8s\n", 45.583f, 5, "hello");
 

יודפס:

o

l

l

e

h

5

0

0

0

3

8

5

.

5

4

כפי שניתן לראות, רוחב השדה הכולל הוא מינימום - אם הנתון כולל מספר תווים גדול מרוחב השדה הוא יודפס במלואו, לכן הפרמטר הראשון מודפס על פני 9 מקומות ולא 8.

 הפרמטר השני, 5, מודפס על פני 8 מקומות ומוצמד לחלק הימני שלהם. גם הפרמטר השלישי, "hello" , מודפס על פני 8 מקומות ומוצמד ימינה.

דיוק

ניתן גם לקבוע את הדיוק שמשמעותו היא בהתאם לטיפוס:

    עבור ממשייים - מספר התווים המודפסים לאחר הנקודה העשרונית.
    עבור שלמים - מספר הספרות המינימלי להדפסה.
    עבור מחרוזת - מספר התווים להדפסה.

הדיוק מצויין מימין לנקודה במחרוזת הבקרה:

 
printf("%8.2f%8.4d%8.3s\n", 45.583f, 5, "hello");
 

יודפס:

l

l

e

h

 

5

0

0

0

 8

5

.

5

4

 

 

 

הצמדה

בברירת מחדל, המספרים המודפסים מוצמדים לימין בפלט. כדי לבצע הצמדה לשמאל של המספרים, מציבים סימן "-" לפני ערך רוחב השדה. לדוגמא:

 
printf("%-8.2f%-8d%-8s\n", 45.583f, 5, "hello");
 

יודפס:

 

 

o

l

l

e

h

 

 

 

 

 

 

5

 

 

 

8

5

 .

 5

 4

מצייני פורמט נוספים

מצייני הפורמט הבאים מוצבים בין הסימן % למציין הטיפוס, או לרוחב השדה - אם קיים.

קביעת short (h) ו- long (l) לשלמים:

התו h המופיע בין הסימן % למציין טיפוס שלם מציין שהפרמטר הוא מסוג short, והתו l מציין שהפרמטר מסוג long:

 
          short s1 = 1234;
          long l1 = 123456789L;
          printf("%ld  %hd", l1, s1);
 

קביעת long (L) לממשיים:

התו L המופיע בין הסימן % למציין טיפוס ממשי מציין שהפרמטר הוא מסוג long double:

 
          long double ld = 34E+33;
          printf("%Lg", ld);
 

הצגת אפסים מקדימים (0):

התו 0 (אפס) בין הסימן % לרוחב השדה מציין מילוי באפסים:

 
          printf("%08.2f %d\n", 45.58f, 5);
 

יודפס:

 
00045.58 5
 


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

קביעת הרווח ע"י פרמטרים (*)

התו * המופיע בין הסימן % למציין הטיפוס מציין שרוחב השדה נמצא ברשימת הפרמטרים במקום המתאים. לדוגמא:

 
          printf("%*.*f %d\n", 8, 2, 45.583f, 5);
 

יודפס:

 
   45.58 5
 

קביעת תצורה ע"י #

התו  #המופיע בין הסימן % למציין הטיפוס מציין תצורה שונה להדפסות הבאות:

    %x, %X - השלם יודפס עם הקידומת 0X או 0x בהתאמה
    ממשיים - הממשי יודפס עם הנקודה העשרונית ללא תלות בדיוק הנדרש

לדוגמא, פלט ההוראה הבאה

 
                   printf("%g %x\n", 45.0f, 0xF5);
 

הוא

 
45 f5
 


כעת, אם נוסיף את התו # במחרוזת הבקרה:

 
                   printf("%#g %#x\n", 45.0f, 0xF5);
 

יודפס:

 
45.0000 0xf5
 

הדפסת +

התו + המופיע בין הסימן % למציין הטיפוס מציין הדפסת מספר חיובי עם הסימן +. (אם המספר הוא שלילי מודפס הסימן "-" ללא תלות במציין זה).

דוגמא:

 
printf("%+d %+7.2f %+d", 22, 23.44, -15);
 

יודפס:

 
+22  +23.44 -15
 

תרגול

קרא/י סעיף זה בספר ובצע/י את תר' 1-2 שבעמ' 98-99.

קלט לפי תבנית ע"י scanf

הפונקציה scanf מבצעת קריאת קלט עפ"י פורמט. השם scanf הוא קיצור של
scan + format, כלומר סריקה אחר נתונים בקלט עפ"י פורמט נתון.

scanf היא פונקציה מקבילה ל- printf הקוראת מהקלט לתוך רשימת פרמטרים עפ"י פורמט נתון, אך עם הבדל אחד משמעותי: במקום הפרמטרים עצמם מועברות הכתובות שלהם.

לדוגמא, בפעולת הקלט למשתנה ממשי

 
float amount;
scanf("%f", &amount);
 

מועברת כתובת המשתנה, &amount, לפונקציה scanf:

הפונקציה scanf קוראת נתונים מהקלט לתוך כתובות שניתנות לה כפרמטרים.

האופרטור &  מציין "הכתובת של": הצבתו לפני שם המשתנה מציינת התייחסות לכתובתו - נעסוק במצביעים בהרחבה בפרק 8, "מצביעים".

scanf מתעלמת מהתווים ה"לבנים" - רווח, טאב ותו שורה חדשה - אלא אם כן סוג הנתון הוא תווי. לדוגמא:

 
int num;
scanf("%d", &num);
printf("The number is %d", num);
 

אם בקלט יהיה כתוב  "123abc", הפונקציה תקרא את המספר 123 ותתעלם מהאותיות abc, כיוון שאינן ספרות.

שאלה: מה היה קורה לו במחרוזת הבקרה היה כתוב %x במקום %d?

תשובה: abc ספרות חוקיות במספור הקסה-דצימלי ולכן הן היו נקראות. המספר הנקרא היה 0x123ABC.

מצייני הטיפוס

הטבלה שבעמ' 100 כוללת את מצייני הטיפוסים עבור scanf.

scanf מנסה להתאים כל תו הנמצא במחרוזת הבקרה לקלט, כולל רווחים. לדוגמא, אם נרצה לקלוט 2 מספרים - שלם וממשי - מופרדים ע"י הסימן "^" נכתוב:

 
int    inum;
float           fnum;
printf("Enter an integer and a float, separated by ^\n");
scanf("%d ^ %f", &inum, &fnum);
printf("%d %f", inum, fnum);
 

עבור הקלט

 
Enter an integer and a float, separated by ^
23  ^  23.45
 


יודפס

 
23 23.450001
 

דוגמאות

נניח שמוגדרים המשתנים

 
int              inum;
float                    fnum;
char                    ch;
 

וכמו כן נניח שמוגדר טיפוס מחרוזת ומשתנה מחרוזת:

 
typedef      char String[256];
String       str;
 

הטבלה הבאה כוללת דוגמאות להוראות קלט ומבנה קלט מתאים:

הוראה



קלט מתאים

הערות

 
scanf("%d %f %c %s", &inum, &fnum, &ch, str);
 

23 23.45 r hello

לאחר המספר הממשי מותאם רווח בקלט ואחריו התו r

 
scanf("%s%n", str, &inum);
 

hello

inum מקבל את הערך 5

 
scanf("%p", &inum);
 

34EF25A1

מספר הקסה-דצימלי בן 8 ספרות מקסימום

בדיקת הצלחת פעולת הקלט

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

שאלה: כיצד נדע אם הקלט הצליח ?

תשובה: הפונקציה scanf מחזירה את מספר הפרמטרים שנקראו באופן תקין מהקלט. ניתן להשתמש בערך זה כדי להחליט אם הקלט היה תקין. לדוגמא:

 
#include <stdio.h>
void  main()
{
          int    num1;
          float num2;
          int    n;
          printf("Please enter 2 numbers - integer and real: ");
        n = scanf("%d %f", &num1, &num2);
          if(n!=2)
                   printf("Incorrect input!");
          else
                   printf("The numbers are: %d %.2f", num1, num2);
}
 

בתכנית מבקשים מהמשתמש להקליד שני מספרים, שלם וממשי. המשתנה n משמש לקריאת הערך המוחזר מהפונקציה scanf

 
n = scanf("%d %f", &num1, &num2);
 

במידה וערך זה שונה מהערך הצפוי - 2 - מדפיסים הודעת שגיאה למשתמש. דוגמא להרצת התכנית עם קלט שגוי:

 
Please enter 2 numbers - integer and real: 
12 word
Incorrect input!
 

קלט / פלט של מחרוזות

כפי שראינו, מחרוזת היא מערך תווים המסתיים בתו מסיים מחרוזת. הדפסת מחרוזת אפשרית ע"י הפונקציה printf בתוספת מזהה הטיפוס %s:

 
typedef char String[256];
 
String  str = "hello";
printf("%s",str);
 

או בקיצור:

 
printf(str);
 

קריאת מחרוזות מתבצעת ע"י מזהה הטיפוס %s , לדוגמא:

 
scanf("%s",str);
 

מחרוזת היא מקרה מיוחד - אין צורך באופרטור הכתובת "&" מכיוון ששמה הוא כתובתה. בפרק 8, "מצביעים", נרחיב בנושא כתובות המשתנים והפרמטרים לפונקציות.

קלט / פלט שורת טקסט ע"י  gets ו- puts

קיימות פונקציות קלט / פלט ייעודיות לקריאה וכתיבה של מחרוזת הפרושה על שורה שלמה:

    gets(str) - פונקציה לקריאת שורת טקסט מהקלט לתוך המחרוזת הנתונה.
    puts(str) - פונקציה להדפסת המחרוזת הנתונה לפלט כשורת טקסט.


שתי הפונקציות מוצהרות בקובץ הספרייה stdio.h ומקבלות כפרמטר מחרוזת:

  - gets קוראת מהקלט את התווים לתוך מחרוזת הנתונה לה כפרמטר ומחליפה את תו מעבר השורה '\n' בתו '\0' המסמן סוף מחרוזת.
  - puts מדפיסה לפלט את התווים מתוך המחרוזת הנתונה תוך החלפת תו סיום המחרוזת '\0' בתו שורה חדשה '\n'.


עיין/י בתכנית הדוגמא שבעמ' 103.

ניתוב קלט / פלט  (I/O Redirection)

הפעלת התכנית ממערכת ההפעלה

לאחר הידור התכנית נוצר קובץ ביצוע הניתן להרצה ממערכת ההפעלה. אופן ההפעלה תלוי במערכת ההפעלה בה עובדים.

לדוגמא, ב- Windows ניתן להפעיל את התכנית מתוך מנהל הקבצים ע"י הקשה כפולה על קובץ הביצוע של התכנית (exe) .

כמו כן ניתן להפעילה מתוך חלון DOS ע"י הקלדת שמה והקשה על Enter. אם שם התכנית הוא prog.exe והיא נמצאת בספרייה  c:\c_course  נבצע:

c:\c_course>  prog

קלט התכנית יינתן ע"י המקלדת ופלט התכנית יוצג למסך.

קלט / פלט תקני (Standard I/O)

כאשר התכנית מבצעת פעולות קלט / פלט ע"י printf או scanf למשל, היא אינה "יודעת" מהיכן מגיע הקלט ולאן מופנה הפלט.

קלט/פלט תקני (Standard I/O) הוא התייחסות כללית למקור הקלט וליעד הפלט של התכנית. אלה תלויים באופן ההפעלה של התכנית ע"י המשתמש.

בברירת מחדל, מקור קלט התכנית הוא המקלדת ויעד הפלט הוא המסך:

ניתוב הקלט והפלט

המשתמש יכול לקבוע את מקור הקלט ואת יעד הפלט בהפעלת התכנית. לדוגמא, ניתן להפנות את הפלט לקובץ במקום למסך:

c:\c_course>  prog > prog.out

התכנית prog.exe תופעל והפלט שלה המבוצע ע"י ההוראות putchar, printf, puts ינותב לקובץ prog.out. למסך לא יודפס דבר.

כמו כן ניתן לקרוא מקובץ את קלט התכנית במקום מהמקלדת.

לדוגמא, אם נרצה לקרוא קלט לתכנית prog.exe מהקובץ prog.in נבצע:

c:\c_course>  prog < prog.in

כעת התכנית לא תמתין לקלט מהמקלדת ע"י המשתמש, אלא תקרא את הנתונים מהקובץ באופן רציף ותמשיך בביצוע:

ניתן לשלב את השניים - כלומר לקרוא מקובץ ולכתוב לקובץ:

c:\c_course>  prog < prog.in > prog.out

במערכות הפעלה רבות קבצים מתארים התקני מערכת, ולכן ניתן להשתמש בהפניית קלט/פלט לקבצים כדי לפשט פעולות מורכבות.

לדוגמא, תחת מערכות ההפעלה Windows / DOS הקובץ prn מתאר את המדפסת - לכן ניתן להדפיס את פלט התכנית prog.exe ע"י:

c:\c_course>  prog > prn

סיכום

  • ספריית הקלט / פלט התקני כוללת פונקציות שונות לביצוע קריאה וכתיבה להתקני הקלט והפלט התקניים (מקלדת ומסך).
  • קיימות פונקציות לתמיכה בקריאה וכתיבה של תווים בודדים (getchar(), putchar()) וכן פונקציות לקריאה וכתיבת מגוון עשיר של טיפוסים: שלם, ממשי, תו ומחרוזת
    (printf(), scanf()).
  • scanf ו- printf כוללות מחרוזת בקרה המכילה מצייני פורמט עבור הפרמטרים המודפסים. ניתן גם לקבוע הצמדות ורווחים בהדפסה ע"י שדות מיוחדים הנלווים למצייני הפורמט. בפונקציה scanf יש להעביר את כתובות המשתנים כפרמטרים.
  • קלט / פלט של מחרוזת בת מילה אחת מבוצע ע"י הפונקציות  printf ו- scanf עם מציין הטיפוס %s. אם המחרוזת מכילה יותר ממילה אחת, ניתן לבצע קלט / פלט של כל השורה ע"י הפונקציות puts ו- gets.
  • ניתן לבצע ניתוב לקלט / פלט התקני כך שמקור הקלט ו/או יעד הפלט יהיו שונים מברירת המחדל (מקלדת ומסך) כגון: פלט לקובץ, קלט מקובץ, פלט למדפסת וכו'. הניתוב מבוצע משורת הפקודה (Command Line) של מערכת ההפעלה.

תרגילי סיכום

בצע/י את תרגילי הסיכום שבעמ' 106.



[ <<< הקודם ] [ תוכן עניינים ] [ הבא >>> ]