On m'a souvent posé cette question en lien avec l'exécution de programmes à travers Visual Studio. Dans ce cas bien précis, si le souhait est d'attendre la fin d'une exécution du programme pour fins de tests, mais pas nécessairement d'attendre la pression d'ue touche à la fin de chaque exécution du programme, le truc le plus simple est d'appuyer Ctrl+F5 – Exécuter sans débogage (plutôt que F5 – Débogage).
Dans un programme console, comment lire une touche au clavier, simplement, si nous ne somme pas préoccupés par la valeur du symbole sur la touche pressée? C'est une question fréquemment posée, particulièrement pour des gens qui souhaitent qu'un programme soit « mis en attente » avant de compléter son exécution.
Tout d'abord, sachez que la plupart des solutions portables impliqueront de lire une touche (ou plus), puis d'appuyer sur la touche <enter>. La raison pour cet état de fait est que la plupart des outils d'entrée / sortie passant par le clavier font ce qu'on nomme du Buffered I/O, ou entrées / sorties tamponnées.
Il y a des raisons pour cette situation : de un, il est typiquement plus efficace (au sens de : permet un plus grand débit) de lire ou d'écrire des blocs de données sur / d'un flux qu'il ne l'est d'écrire un caractères à la fois. De même, certains types de terminaux ne permettent simplement pas de lire les entrées un caractère à la fois, ne réalisant un transfert de données que sur pression de la touche <enter>.
Si une solution non-portable vous convient, sous Microsoft Windows, alors un programme C++ comme le suivant fera le travail :
#include <conio.h> // spécifique à la plateforme
#include <iostream>
int main() {
using namespace std; // cout, cin
cout << "Appuyez sur une touche pour completer le programme..." << flush;
getch(); // non-portable; pas besoin d'appuyer sur enter
}
Le reste de ce texte se limitera aux options portables.
La façon la plus simple de lire une touche suivie d'une pression de la touche <enter> en Java est probablement la méthode System.in.read(), qui retourne la valeur entière de la touche pressée (p. ex. : 65 pour la touche 'A', selon toute probabilité). Par exemple :
import java.io.*;
public class Z {
public static void main(String[] args) {
try {
System.in.read();
} catch (IOException ioe) {
}
}
}
Notez que System.in est l'entrée standard, et que la méthode read() provient de la classe InputStream. Étant a priori abstraite et générale, elle est susceptible de lever une exception, et le fait que Java utilise des exceptions déclarées (Checked Exceptions) ce qui impose au code client le fardeau d'insérer un bloc try...catch... au point d'appel.
La façon la plus simple de lire une touche en C# est probablement la méthode ReadKey() de l'objet Console. Par exemple :
using System;
namespace z
{
class Program
{
static void Main(string[] args)
{
Console.ReadKey();
}
}
}
Pas besoin d'appuyer sur <enter>, du fait que C# ne vise pas à offrir ce service de manière très générale. La valeur retournée par cette méthode est une ConsoleKeyInfo, constante modélisant le caractère Unicode consommé au clavier (incluant les touches de modification telles que CTRL, ALT ou SHIFT).
En C++, l'entrée standard est std::cin (ou std::wcin si le souhait est de consommer des caractères étendus), et une manière simple de consommer un caractère est d'utiliser sa méthode get(), tout simplement. Par exemple :
#include <iostream>
int main() {
using namespace std;
char c;
cin.get(c);
}
Cette technique aurait pu être appliquée aux autres exemples plus haut, d'ailleurs. Dans le cas où la valeur lue ne nous intéresse pas, il est possible de faire plus simple encore en ignorant, littéralement, ce qui a été consommé au clavier à l'aide de la méthode ignore() :
#include <iostream>
int main() {
using namespace std;
cin.ignore();
}
Ceci consomme les données lues jusqu'à un saut de ligne (par défaut; il est possible d'utiliser un autre marqueur de fin que celui-là), et n'en tient pas compte tout simplement.
Notez qu'en C++, les erreurs de lecture ne sont pas rapportées par une levée d'exception; la modalité est de prendre par référence l'objet à lire (ici, le char nommé c) et de retourner une référence sur le flux duquel la lecture a été réalisée. Ce flux peut se tester par la suite et se comportera comme un booléen faux dans le cas d'une erreur.
Par exemple, si nous souhaitons lire une touche au clavier et l'utiliser si aucune erreur n'est survenue, la procédure est :
C# | Java | C++ |
---|---|---|
|
|
|
Voilà.