# קלט/פלט בסיסי📖 שיעור

## מה זה?

`Console.WriteLine` כבר מוכר — אבל תוכנית אמיתית צריכה גם **לקבל** מידע מהמשתמש, לא רק להדפיס. `Console.ReadLine()` עושה בדיוק את זה — אבל מחזירה תמיד `string`, גם אם המשתמש הקליד מספר. אם ננסה להשתמש בקלט כמספר בלי המרה מפורשת, C# (בגלל ה-Static Typing שלמדנו) פשוט לא תרשה — צריך להמיר במפורש.

## מילות מפתח שחשוב לזכור

• `Console.ReadLine()` — קורא שורת טקסט מהמשתמש; מחזיר תמיד `string` (או `null` אם אין קלט)

• `int.Parse()` — ממיר `string` ל-`int`; זורק חריגה (Exception) אם הטקסט לא מספר תקין

• `int.TryParse()` — ניסיון המרה "בטוח": מחזיר `bool` (הצליח/לא) בלי לזרוק חריגה

• `Convert.ToInt32()` — דרך נוספת להמרה, דומה ל-`Parse` אך מטפלת גם ב-`null` (מחזירה 0)

```csharp
Console.Write("What's your name? ");
string name = Console.ReadLine();

Console.Write("What's your age? ");
string ageInput = Console.ReadLine();
int age = int.Parse(ageInput);   // explicit conversion — string is not int

Console.WriteLine($"Hello {name}, in a year you'll be {age + 1}");
```

```csharp
// TryParse — the safe way, no risk of crashing on invalid input
Console.Write("What's your age? ");
string input = Console.ReadLine();

if (int.TryParse(input, out int age))
{
    Console.WriteLine($"Your age: {age}");
}
else
{
    Console.WriteLine("Invalid input — a number is required");
}
```

## הסבר עיקרי

למה `ReadLine` תמיד מחזירה `string` — מנקודת המבט של הקונסולה, כל מה שהמשתמש מקליד הוא טקסט גולמי — אין דרך לדעת מראש אם הכוונה הייתה למספר, שם, או כתובת. C# משאירה את ההחלטה למפתח: אתם קובעים אם ואיך להמיר את הטקסט לטיפוס שאתם צריכים.

`Parse` מול `TryParse` — `int.Parse("abc")` **זורק חריגה** (`FormatException`) אם הטקסט לא מספר תקין, מה שיכול לקרוס את התוכנית אם לא מטפלים בזה (נלמד על טיפול בחריגות בהמשך). `int.TryParse` היא הגרסה ה"מנומסת": היא מנסה להמיר, ומחזירה `true`/`false` דרך ה-`out` (נלמד עליו בהמשך) בלי לזרוק שום דבר — מתאימה כברירת מחדל כשהקלט לא מובטח להיות תקין, כלומר כמעט תמיד כשמדובר בקלט ממשתמש.

Interpolated Strings (`$"..."`)‏ — ה-`$` לפני מחרוזת מאפשר להטמיע ביטויי C# ישירות בתוכה עם `{}`, כמו `$"שלום {name}"` — נוח בהרבה מחיבור ידני עם `+`.

## יתרונות

`ReadLine` פשוט וישיר לקלט טקסטואלי בסיסי; `TryParse` מונע קריסות על קלט לא צפוי בלי צורך בטיפול-חריגות מסובך; Interpolated Strings הופכות בניית הודעות עם משתנים לקריאה בהרבה מחיבור מחרוזות ידני.

## חסרונות

`Console.ReadLine` חוסמת (Blocking) את התוכנית עד שהמשתמש מקליד ולוחץ Enter — לא מתאים לתוכניות שצריכות תגובתיות מיידית; המרות טיפוסים חוזרות (`int.Parse`, ואז שוב `double.Parse` וכו') הופכות קוד קלט למרובה-שורות גם למשימות פשוטות.

## נקודות חשובות

• `Console.ReadLine()` תמיד מחזירה `string`, גם כשהמשתמש הקליד מספר

• `int.Parse` זורק חריגה על קלט לא תקין; `int.TryParse` מחזירה `bool` בלי לזרוק

• `TryParse` היא ברירת המחדל הבטוחה לכל קלט שמגיע ממשתמש אמיתי

• `$"..."` (Interpolated String) מטמיע ביטויי C# בתוך מחרוזת עם `{}`

## טעויות נפוצות

• לנסות להשתמש בתוצאה של `ReadLine` כמספר ישירות בלי המרה, ולקבל שגיאת קומפילציה

• להשתמש ב-`int.Parse` על קלט משתמש בלי טיפול בחריגה אפשרית — קלט לא תקין מקריס את התוכנית

• לשכוח שה-`out` פרמטר של `TryParse` (`out int age`) הוא מה שמחזיק את התוצאה המומרת בפועל

## סיכום

`Console.ReadLine()` מקבלת קלט תמיד כ-`string`, ודורשת המרה מפורשת (`int.Parse`/`TryParse`) לכל טיפוס אחר שנרצה. `TryParse` היא הדרך הבטוחה — מחזירה `bool` הצלחה/כישלון בלי לזרוק חריגה — ומתאימה כברירת מחדל לכל קלט שמגיע ממשתמש שאי אפשר לסמוך על תקינותו מראש.

## דוקומנטציה רשמית

[Microsoft Learn — Console.ReadLine](https://learn.microsoft.com/dotnet/api/system.console.readline)

[Microsoft Learn — int.TryParse](https://learn.microsoft.com/dotnet/api/system.int32.tryparse)

---

## תרגילים

### תרגיל 1 — מחשבון גיל פשוט

**המשימה:** בקשו מהמשתמש להקליד שנת לידה, המירו ל-`int` עם `int.Parse`, וחשבו והדפיסו את הגיל המשוער (2026 פחות שנת הלידה).

**בדיקה:** הזנת `2000` מדפיסה גיל `26`.

### תרגיל 2 — קלט בטוח עם TryParse

**המשימה:** קחו את תרגיל 1 והמירו אותו להשתמש ב-`int.TryParse` במקום `int.Parse`, כך שקלט לא תקין (למשל `"abc"`) ידפיס הודעת שגיאה ידידותית במקום לקרוס.

**בדיקה:** הזנת `"abc"` מדפיסה הודעת שגיאה ברורה, בלי שהתוכנית קורסת; הזנת מספר תקין ממשיכה לחשב את הגיל כרגיל.

---

## פרויקט מסכם

**המשימה:** כתבו תוכנית "מחשבון BMI" שמקבלת מהמשתמש משקל (ק"ג) וגובה (מטרים), ומחשבת ומדפיסה את מדד ה-BMI (`משקל / (גובה * גובה)`).

**דרישות:**
1. שני קלטים נפרדים עם `Console.ReadLine`, שני שדות (`weight`, `height`)
2. שימוש ב-`double.TryParse` לשני הקלטים (לא `Parse` רגיל)
3. אם אחד הקלטים לא תקין — הדפיסו הודעת שגיאה וסיימו בלי לחשב
4. אם שני הקלטים תקינים — הדפיסו את ה-BMI מעוגל לשתי ספרות אחרי הנקודה (`.ToString("F2")`)

**בדיקה:** קלט `70` ו-`1.75` מדפיס BMI של כ-`22.86`; קלט לא תקין (למשל טקסט חופשי) מדפיס הודעת שגיאה בלי לקרוס.

## מה בפרק הבא

בפרק הבא — **תנאים ולולאות**: איך גורמים לתוכנית "להחליט" בין כמה אפשרויות עם `if`/`else`, ולחזור על פעולה כמה פעמים עם `for`/`while`.
