Aller au contenu principal

Saisie console et aléatoire

Notions théoriques

Console.ReadLine() — lire une ligne

Console.Write("Entrez votre prénom : ");
string? saisie = Console.ReadLine(); // retourne string? (nullable)
Console.WriteLine($"Bonjour, {saisie} !");
string? — type nullable

Console.ReadLine() retourne string? (avec le ?) car il peut retourner null dans certains cas (fin de flux, redirection). Le ? signale que la variable peut être nulle. Avec <Nullable>enable</Nullable> dans le .csproj, le compilateur vous avertit si vous utilisez une valeur nullable sans vérification.

Convertir la saisie en nombre

Console.Write("Entrez votre âge : ");
string? saisie = Console.ReadLine();

// Méthode 1 : Parse (lève FormatException si invalide)
int age = int.Parse(saisie!); // ! = "je sais que ce n'est pas null"

// Méthode 2 : TryParse (recommandée — pas d'exception)
if (int.TryParse(saisie, out int ageValide))
{
Console.WriteLine($"Vous avez {ageValide} ans.");
}
else
{
Console.WriteLine("Saisie invalide.");
}

Boucle de validation avec do-while

int nombre;
do
{
Console.Write("Entrez un nombre entre 1 et 100 : ");
string? saisie = Console.ReadLine();

if (!int.TryParse(saisie, out nombre))
nombre = -1; // force une nouvelle itération

} while (nombre < 1 || nombre > 100);

Console.WriteLine($"Vous avez saisi : {nombre}");

Console.ReadKey() — lire un seul caractère

Console.Write("Appuyez sur une touche pour continuer...");
ConsoleKeyInfo touche = Console.ReadKey(intercept: true); // intercept = ne pas afficher

Console.WriteLine($"\nVous avez appuyé sur : {touche.Key}");

// Tester une touche spécifique
if (touche.Key == ConsoleKey.Enter)
Console.WriteLine("Entrée détectée !");

Nombres aléatoires avec Random

// Utiliser Random.Shared (instance partagée, thread-safe, recommandée depuis .NET 6)
int de = Random.Shared.Next(1, 7); // entre 1 et 6 inclus (Next(min, max) exclut max)
Console.WriteLine($"Dé : {de}");

double reel = Random.Shared.NextDouble(); // entre 0.0 et 1.0
int boule = Random.Shared.Next(1, 50); // loto : entre 1 et 49

// Avec une graine fixe (reproductible — utile pour les tests)
var rng = new Random(42);
Console.WriteLine(rng.Next(1, 100)); // toujours le même résultat avec la même graine
Random.Shared depuis .NET 6

Avant .NET 6, il fallait créer new Random() à chaque fois, ce qui pouvait donner des séquences identiques si les objets étaient créés trop rapidement. Random.Shared est une instance thread-safe partagée qui résout ces problèmes. Utilisez-la par défaut.

Exemple pratique

// Jeu de devinette
int secret = Random.Shared.Next(1, 101); // nombre entre 1 et 100
int tentatives = 0;
int maxTentatives = 7;

Console.WriteLine("=== Jeu de devinette ===");
Console.WriteLine($"Devinez le nombre entre 1 et 100 (max {maxTentatives} essais)\n");

int saisie = 0;
do
{
Console.Write($"Essai {tentatives + 1}/{maxTentatives} : ");
string? input = Console.ReadLine();

if (!int.TryParse(input, out saisie) || saisie < 1 || saisie > 100)
{
Console.WriteLine(" → Saisie invalide (entrez un nombre entre 1 et 100).");
continue;
}

tentatives++;

if (saisie < secret)
Console.WriteLine(" → Trop petit !");
else if (saisie > secret)
Console.WriteLine(" → Trop grand !");

} while (saisie != secret && tentatives < maxTentatives);

if (saisie == secret)
Console.WriteLine($"\n✓ Bravo ! Trouvé en {tentatives} essai(s) !");
else
Console.WriteLine($"\n✗ Perdu ! Le nombre était {secret}.");

Test de mémorisation/compréhension


Pourquoi `Console.ReadLine()` retourne-t-il `string?` et non `string` ?


Quelle méthode convertit une chaîne en entier SANS risquer une exception ?


Que retourne `Random.Shared.Next(1, 7)` ?


Quelle boucle est la plus adaptée pour valider une saisie utilisateur (doit s'exécuter au moins une fois) ?


Quelle est la différence entre `Console.ReadLine()` et `Console.ReadKey()` ?


TP pour réfléchir et résoudre des problèmes

Vous allez créer un calculateur de notes interactif.

Étape 1 — Saisir des notes en boucle

Demandez des notes jusqu'à ce que l'utilisateur tape "fin".


Bonne pratique - Valider la plage en plus du format

double.TryParse vérifie que la saisie est un nombre valide, mais pas qu'il est dans la plage 0-20. Ajoutez toujours la validation métier (note >= 0 && note <= 20) en plus de la validation de format.

Étape 2 — Valider la plage avec TryParse

Utilisez TryParse pour sécuriser la conversion.


Bonne pratique - TryParse plutôt que Parse

double.TryParse ne lève jamais d'exception — il retourne false si la conversion échoue. double.Parse lève une FormatException. Pour les saisies utilisateur (qui peuvent toujours être invalides), utilisez toujours TryParse.

Étape 3 — Afficher les statistiques

Calculez et affichez la moyenne, le min et le max.


Bonne pratique - Toujours vérifier Count avant Min/Max

notes.Min() et notes.Max() lèvent une exception si la liste est vide. Vérifiez toujours notes.Count > 0 (ou notes.Any()) avant d'appeler ces méthodes sur une collection potentiellement vide.

📌 Une solution