HOWTO · C++
Déclarer une chaîne de caractères multiligne en C++
Cet article montre comment déclarer une chaîne de caractères multiligne en C++.
Sur cette page
Les chaînes multilignes sont utiles lorsque vous manipulez de longs textes ou souhaitez conserver la mise en forme dans votre code source. C++ n’a pas de type dédié aux chaînes multilignes, mais il offre plusieurs façons d’en construire une : des littéraux de chaîne adjacents, des littéraux de chaîne bruts, la jonction antislash-saut de ligne et la conversion en chaîne par le préprocesseur. Ces techniques diffèrent surtout par le fait que les sauts de ligne du code source deviennent ou non des sauts de ligne dans la valeur.
Ce guide présente chaque approche avec des exemples exécutables et se termine par une comparaison pour vous aider à choisir celle qui convient à votre code. Les exemples et leurs sorties conservent leur texte anglais d’origine.
Construire une chaîne multiligne avec des littéraux de chaîne adjacents
Lorsque le compilateur rencontre plusieurs littéraux de chaîne entre guillemets doubles placés côte à côte et séparés uniquement par des caractères d’espacement, il les concatène en une seule valeur lors de la compilation. Répartir un littéral sur plusieurs lignes du source est un choix de mise en forme uniquement : aucun saut de ligne n’est ajouté à la valeur, sauf si vous écrivez vous-même \n, et les espaces doivent être incluses explicitement aux endroits où les mots doivent rester séparés.
Exécutez cet exemple :
Le code et les libellés ou sorties affichés dans cette section restent en anglais.
#include <iostream>
#include <string>
int main() {
std::string message =
"I love"
" getting my doubts solved"
" by the help of Delft Stack Tutorials.";
std::cout << message << std::endl;
return 0;
}
I love getting my doubts solved by the help of Delft Stack Tutorials.
La concaténation des littéraux adjacents fonctionne de la même façon lorsque la destination est un const char * — un pointeur vers le littéral en lecture seule — plutôt qu’un objet std::string :
#include <cstdio>
int main() {
const char *lines =
"Line 1 "
"Line 2 "
"Line 3";
std::printf("%s\n", lines);
return 0;
}
Line 1 Line 2 Line 3
Choisissez std::string lorsque le texte sera modifié ou transmis à des API qui manipulent des chaînes ; un const char * convient à un texte statique qui est seulement affiché ou inspecté.
Conserver les sauts de ligne avec des littéraux de chaîne bruts
C++11 a ajouté les littéraux de chaîne bruts, qui permettent aux sauts de ligne physiques d’exister dans le littéral lui-même. Tout ce qui se trouve entre R"( et )" — y compris les sauts de ligne, l’indentation, les guillemets et les antislashs — est intégré tel quel à la valeur ; aucune séquence d’échappement n’est donc nécessaire :
Le code et les libellés ou sorties affichés dans cette section restent en anglais.
#include <iostream>
#include <string>
int main() {
std::string page = R"(I love
getting my doubts solved
by the help of Delft Stack Tutorials.)";
std::cout << page << std::endl;
return 0;
}
I love
getting my doubts solved
by the help of Delft Stack Tutorials.
Comme le contenu est copié tel quel, surveillez deux détails : un saut de ligne placé immédiatement après R"( est stocké dans la valeur, et l’indentation avant les lignes suivantes est également conservée. Si votre texte contient la séquence )", choisissez un délimiteur personnalisé comme R"tag(...)tag" : le marqueur de fermeture exige alors l’étiquette, si bien qu’un simple )" dans le texte ne termine pas le littéral.
Continuer un littéral de chaîne par jonction antislash-saut de ligne
Un antislash placé en tout dernier caractère d’une ligne de code joint cette ligne à la suivante avant la compilation. À l’intérieur d’un littéral de chaîne, cela permet au littéral de s’étendre sur plusieurs lignes du source, mais le saut de ligne ainsi joint est supprimé : il ne produit pas de saut de ligne dans la valeur. C’est la différence essentielle avec la séquence d’échappement \n, qui, elle, ajoute un saut de ligne :
Le code et les libellés ou sorties affichés dans cette section restent en anglais.
#include <cstdio>
int main() {
const char *text =
"First line\n"
"Second line\n\
Third line\n";
std::printf("%s", text);
return 0;
}
First line
Second line
Third line
La sortie montre les deux mécanismes à l’œuvre : chaque \n écrit un saut de ligne, tandis que la jonction par antislash relie seulement les lignes du source — et les espaces initiales de la ligne continuée deviennent des caractères réels dans la valeur. Cette sensibilité aux espaces est le principal danger : l’indentation ajoutée pour la lisibilité se retrouve dans la chaîne, et tout caractère placé après l’antislash, même une espace, rompt la jonction. N’utilisez cette technique que là où vous contrôlez totalement la mise en page environnante.
Comprendre les limites de la conversion en chaîne par macro
Une macro variadique peut transformer ses arguments en littéral de chaîne grâce à l’opérateur de conversion en chaîne, comme dans #define MULTILINE_STRING(...) #__VA_ARGS__. Transmettre un texte réparti sur plusieurs lignes produit un seul littéral entre guillemets, mais le préprocesseur réduit chaque suite de caractères d’espacement, y compris les sauts de ligne, à une seule espace :
Le code et les libellés ou sorties affichés dans cette section restent en anglais.
#include <iostream>
#include <string>
#define MULTILINE_STRING(...) #__VA_ARGS__
int main() {
std::string message = MULTILINE_STRING(
I love getting my doubts solved by the help of Delft Stack Tutorials.);
std::cout << message << std::endl;
return 0;
}
I love getting my doubts solved by the help of Delft Stack Tutorials.
Cela fait de la conversion en chaîne par macro une option contrainte, et non un outil général pour créer des chaînes multilignes. Elle ne peut pas conserver les sauts de ligne, le texte des arguments est décomposé en jetons plutôt que traité comme du contenu de chaîne (de sorte qu’une ponctuation inattendue peut produire des résultats surprenants), et le code reposant sur des macros est plus difficile à lire et à déboguer. N’y recourez que lorsque du code piloté par le préprocesseur doit réellement transformer des jetons en texte.
Choisir la technique de chaîne multiligne adaptée
- Les littéraux de chaîne bruts sont le choix par défaut lorsque les sauts de ligne, l’indentation ou des caractères tels que
\et"doivent être conservés tels quels dans la valeur : idéal pour les blocs de texte intégrés, le JSON, le SQL ou les expressions régulières. - Les littéraux de chaîne adjacents offrent un contrôle précis de la valeur tout en gardant des lignes de source courtes ; les espaces et les
\nsont tous explicites, donc rien d’involontaire ne s’y glisse. - La jonction antislash-saut de ligne est fragile et sensible à l’indentation ; elle survit surtout dans le code hérité et dans les définitions de macros, où elle reste nécessaire pour poursuivre une définition sur plusieurs lignes.
- La conversion en chaîne par macro ne convient qu’au code qui s’appuie fortement sur le préprocesseur et doit réellement convertir des jetons en texte.
Pour une valeur qui s’étend réellement sur plusieurs lignes, utilisez un littéral de chaîne brut. Pour une longue valeur destinée à tenir sur une seule ligne mais mise en forme sur plusieurs lignes dans votre source, les littéraux adjacents sont la solution la plus claire — et ils s’associent naturellement à std::string comme à const char *.