Qualifier les caractères
Il arrive souvent qu'on souhaite qualifier les caractères dans un programme
C++,
par exemple dans le but d'identifier si un caractère est un blanc (espace,
tabulation, changement de ligne, etc.), une ponctuation (virgule,
parenthèse ouvrante, apostrophe, etc.), une lettre, un chiffre et
ainsi de suite.
La tradition
C est d'utiliser les fonctions suivantes, définies dans
<ctype.h> (ou, en
C++, dans <cctype>) :
Nom |
Rôle |
Exemple |
std::isalnum()
|
Retourne true si et seulement si le
char passé en paramètre est alphanumérique
|
// inclure <cctype> et <iostream>
char c;
if (std::cin >> c; && std::isalnum(c))
{
// c est alphanumérique
}
|
std::isalpha()
|
Retourne true si et seulement si le
char passé en paramètre est alphabétique
|
// inclure <cctype> et <iostream>
char c;
if (std::cin >> c; && std::isalpha(c))
{
// c est alphabétique
}
|
std::iscntrl()
|
Retourne true si et seulement si le
char passé en paramètre est un caractère de contrôle
|
// inclure <cctype> et <iostream>
char c;
if (std::cin >> c; && std::iscntrl(c))
{
// c est un caractère de contrôle
}
|
std::isgraph()
|
Retourne true si et seulement si le
char passé en paramètre est une caractère graphique
|
// inclure <cctype> et <iostream>
char c;
if (std::cin >> c; && std::isgraph(c))
{
// c est un caractère graphique
}
|
std::islower()
|
Retourne true si et seulement si le
char passé en paramètre est une lettre minuscule
|
// inclure <cctype> et <iostream>
char c;
if (std::cin >> c; && std::islower(c))
{
// c est une lettre minuscule
}
|
std::isprint()
|
Retourne true si et seulement si le
char passé en paramètre est affichable
|
// inclure <cctype> et <iostream>
char c;
if (std::cin >> c; && std::isprint(c))
{
// c est affichable
}
|
std::ispunct()
|
Retourne true si et seulement si le
char passé en paramètre est un symbole de ponctuation
|
// inclure <cctype> et <iostream>
char c;
if (std::cin >> c; && std::ispunct(c))
{
// c est une ponctuation
}
|
std::isspace()
|
Retourne true si et seulement si le
char passé en paramètre est un caractère d'espacement (un blanc)
|
// inclure <cctype> et <iostream>
char c;
if (std::cin >> c; && std::isspace(c))
{
// c est un blanc
}
|
std::isupper()
|
Retourne true si et seulement si le
char passé en paramètre est une lettre majuscule
|
// inclure <cctype> et <iostream>
char c;
if (std::cin >> c; && std::isupper(c))
{
// c est une lettre majuscule
}
|
std::isxdigit()
|
Retourne true si et seulement si le
char passé en paramètre est un chiffre hexadécimal
|
// inclure <cctype> et <iostream>
char c;
if (std::cin >> c; && std::isxdigit(c))
{
// c est un chiffre hexadécimal
}
|
std::tolower()
|
Retourne l'équivalent minuscule de son paramètre (s'il y a lieu)
|
// inclure <cctype> et <iostream>
char c;
if (std::cin >> c)
{
std::cout << std::tolower(c);
}
|
std::toupper()
|
Retourne l'équivalent majuscule de son paramètre (s'il y a lieu)
|
// inclure <cctype> et <iostream>
char c;
if (std::cin >> c)
{
std::cout << std::toupper(c);
}
|
Toutes les fonctions de <cctype> n'ont de sens
qu'avec les caractères américains standard. Pour des raisons
d'implémentation, elle planteront si on leur passe, par exemple, un caractère
accentué.
Pour cette raison, on leur préférera en
C++ des versions plus sophistiquées provenant du fichier d'en-tête
<locale> qui, lui, permet de gérer le concept de caractère
associé à une culture, américaine ou autre.
Ces versions que je qualifierais de plus modernes des fonctions de
<cctype> ressemblent beaucoup à leurs prédécesseures à
ceci près qu'elles prennent deux paramètres plutôt qu'un seul. Le premier
paramètre est (dans chaque cas) le caractère sur lequel la fonction doit
opérer et le second paramètre est une référence à la culture
courante.
En
C++, la culture d'un lieu est décrite par une instance de
std::locale. Instancier un std::locale
peut se faire comme suit :
- sans paramètres (donc std::locale{}), ce qui
équivaut à obtenir une référence constante sur la culture dite
classique (au sens du langage
C – on parle ici de la culture américaine);
- avec comme paramètre une chaîne de caractères vide (donc
std::locale{""}), ce qui équivaut à obtenir une référence
constante sur la culture dans laquelle s'exécute le programme (probablement
Français-Canada sur vos postes); ou
- avec comme paramètre une chaîne de caractères non vide représentant un
nom de culture précis, ce qui équivaut à obtenir une référence constante
sur la culture décrite par ce nom.
Les exemples ci-dessous s'appliquent aux versions de
<locale>. La colonne Rôle n'a pas été répétée;
référez-vous à la table précédente
pour des détails.
Il est nettement préférable de privilégier la version à deux
paramètres de <locale> à celle à un
seul paramètre de <cctype>, la première faisant
tout ce que fait la seconde... et même plus.
Nom |
Exemple |
std::isalnum()
|
// inclure <locale> et <iostream>
char c;
if (std::cin >> c; && std::isalnum(c, std::locale{}))
{
// c est alphanumérique
}
|
std::isalpha()
|
// inclure <locale> et <iostream>
char c;
if (std::cin >> c; && std::isalpha(c, std::locale{}))
{
// c est alphabétique
}
|
std::iscntrl()
|
// inclure <locale> et <iostream>
char c;
if (std::cin >> c; && std::iscntrl(c, std::locale{}))
{
// c est un caractère de contrôle
}
|
std::isgraph()
|
// inclure <locale> et <iostream>
char c;
if (std::cin >> c; && std::isgraph(c, std::locale{}))
{
// c est un caractère graphique
}
|
std::islower()
|
// inclure <locale> et <iostream>
char c;
if (std::cin >> c; && std::islower(c, std::locale{}))
{
// c est une lettre minuscule
}
|
std::isprint()
|
// inclure <locale> et <iostream>
char c;
if (std::cin >> c; && std::isprint(c, std::locale{}))
{
// c est affichable
}
|
std::ispunct()
|
// inclure <locale> et <iostream>
char c;
if (std::cin >> c; && std::ispunct(c, std::locale{}))
{
// c est une ponctuation
}
|
std::isspace()
|
// inclure <locale> et <iostream>
char c;
if (std::cin >> c; && std::isspace(c, std::locale{}))
{
// c est un blanc
}
|
std::isupper()
|
// inclure <locale> et <iostream>
char c;
if (std::cin >> c; && std::isupper(c, std::locale{}))
{
// c est une lettre majuscule
}
|
std::isxdigit()
|
// inclure <locale> et <iostream>
char c;
if (std::cin >> c; && std::isxdigit(c, std::locale{}))
{
// c est un chiffre hexadécimal
}
|
std::tolower()
|
// inclure <locale> et <iostream>
char c;
if (std::cin >> c)
{
std::cout << std::tolower(c, std::locale{});
}
|
std::toupper()
|
// inclure <locale> et <iostream>
char c;
if (std::cin >> c)
{
std::cout << std::toupper(c, std::locale{});
}
|
La version de <locale> fonctionne à la fois
avec des caractères codés sur un octet (des
char) et avec les caractères étendus, codés sur deux octets (des
wchar_t).
Si vous souhaitez manipuler des caractères accentués, par exemple, il est
nettement préférable de procéder à l'aide de caractères étendus pour
lesquels ces caractères ont une représentation standard (sur un
char, le sens de
'é' peut varier et, en général, les fonctions de
<locale> et de <cctype> vont planter...
demandez à votre professeur de vous expliquer pourquoi).
Utiliser les fonctions de <locale> avec des
caractères étendus (donc incluant entre autres les accents) va comme suit.
Nom |
Exemple |
std::isalnum()
|
// inclure <locale> et <iostream>
wchar_t c;
if (std::wcin >> c; && std::isalnum(c, std::locale{}))
{
// c est alphanumérique
}
|
std::isalpha()
|
// inclure <locale> et <iostream>
wchar_t c;
if (std::wcin >> c; && std::isalpha(c, std::locale{}))
{
// c est alphabétique
}
|
std::iscntrl()
|
// inclure <locale> et <iostream>
wchar_t c;
if (std::wcin >> c; && std::iscntrl(c, std::locale{}))
{
// c est un caractère de contrôle
}
|
std::isgraph()
|
// inclure <locale> et <iostream>
wchar_t c;
if (std::wcin >> c; && std::isgraph(c, std::locale{}))
{
// c est un caractère graphique
}
|
std::islower()
|
// inclure <locale> et <iostream>
wchar_t c;
if (std::wcin >> c; && std::islower(c, std::locale{}))
{
// c est une lettre minuscule
}
|
std::isprint()
|
// inclure <locale> et <iostream>
wchar_t c;
if (std::wcin >> c; && std::isprint(c, std::locale{}))
{
// c est affichable
}
|
std::ispunct()
|
// inclure <locale> et <iostream>
wchar_t c;
if (std::wcin >> c; && std::ispunct(c, std::locale{}))
{
// c est une ponctuation
}
|
std::isspace()
|
// inclure <locale> et <iostream>
wchar_t c;
if (std::wcin >> c; && std::isspace(c, std::locale{}))
{
// c est un blanc
}
|
std::isupper()
|
// inclure <locale> et <iostream>
wchar_t c;
if (std::wcin >> c; && std::isupper(c, std::locale{}))
{
// c est une lettre majuscule
}
|
std::isxdigit()
|
// inclure <locale> et <iostream>
wchar_t c;
if (std::wcin >> c; && std::isxdigit(c, std::locale{}))
{
// c est un chiffre hexadécimal
}
|
std::tolower()
|
// inclure <locale> et <iostream>
wchar_t c;
if (std::wcin >> c)
{
std::wcout << std::tolower(c, std::locale{});
}
|
std::toupper()
|
// inclure <locale> et <iostream>
wchar_t c;
if (std::wcin >> c)
{
std::wcout << std::toupper(c, std::locale{});
}
|