{fmt} est une bibliothèque de formatage open source offrant une alternative rapide et sûre aux iostreams C stdio et C++.
Si vous aimez ce projet, pensez à faire un don à l'un des fonds qui viennent en aide aux victimes de la guerre en Ukraine : https://www.stopputin.net/.
Documentation
Aide-mémoire
Q&A : posez des questions sur StackOverflow avec le tag fmt.
Essayez {fmt} dans l'Explorateur du compilateur.
API au format simple avec arguments de position pour la localisation
Implémentation de C++20 std::format et C++23 std::print
Syntaxe de chaîne de format similaire au format Python
Formateur de virgule flottante IEEE 754 rapide avec garanties d'arrondi, de brièveté et d'aller-retour corrects grâce à l'algorithme Dragonbox
Prise en charge d'Unicode portable
Implémentation sécurisée de printf, y compris l'extension POSIX pour les arguments de position
Extensibilité : prise en charge des types définis par l'utilisateur
Hautes performances : plus rapide que les implémentations de bibliothèques standard courantes de (s)printf
, iostreams, to_string
et to_chars
, voir Tests de vitesse et Conversion de cent millions d'entiers en chaînes par seconde
Petite taille de code à la fois en termes de code source avec une configuration minimale composée de seulement trois fichiers, core.h
, format.h
et format-inl.h
, et de code compilé ; voir Temps de compilation et surcharge du code
Fiabilité : la bibliothèque dispose d'un ensemble complet de tests et est continuellement fuzzée
Sécurité : la bibliothèque est entièrement sécurisée, les erreurs de format des chaînes peuvent être signalées au moment de la compilation, la gestion automatique de la mémoire évite les erreurs de dépassement de tampon.
Facilité d'utilisation : petite base de code autonome, pas de dépendances externes, licence MIT permissive
Portabilité avec une sortie cohérente sur toutes les plates-formes et prise en charge des anciens compilateurs
Nettoyer la base de code sans avertissement, même à des niveaux d'avertissement élevés tels que -Wall -Wextra -pedantic
Indépendance locale par défaut
Configuration facultative d'en-tête uniquement activée avec la macro FMT_HEADER_ONLY
Voir la documentation pour plus de détails.
Imprimer sur la sortie standard (exécuter)
#include <fmt/core.h>int main() { fmt::print("Bonjour le monde !n"); }
Formater une chaîne (exécuter)
std::string s = fmt::format("La réponse est {}.", 42);// s == "La réponse est 42."
Formater une chaîne à l'aide d'arguments de position (exécuter)
std::string s = fmt::format("Je préfère être {1} que {0}.", "right", "happy");// s == "Je préfère être heureux que bien ".
Imprimer les dates et heures (exécuter)
#include <fmt/chrono.h>int main() { auto now = std::chrono::system_clock::now(); fmt::print("Date et heure : {}n", maintenant); fmt::print("Heure : {:%H:%M}n", maintenant); }
Sortir:
Date and time: 2023-12-26 19:10:31.557195597 Time: 19:10
Imprimer un conteneur (exécuter)
#include <vecteur>#include <fmt/ranges.h>int main() { std::vecteur<int> v = {1, 2, 3}; fmt::print("{}n", v); }
Sortir:
[1, 2, 3]
Vérifier une chaîne de format au moment de la compilation
std::string s = fmt::format("{:d}", "Je ne suis pas un nombre");
Cela donne une erreur de compilation en C++20 car d
est un spécificateur de format non valide pour une chaîne.
Écrire un fichier à partir d'un seul thread
#include <fmt/os.h>int main() { auto out = fmt::output_file("guide.txt"); out.print("Ne pas {}", "Panique"); }
Cela peut être 5 à 9 fois plus rapide que fprintf.
Imprimez avec des couleurs et des styles de texte
#include <fmt/color.h>int main() { fmt::print(fg(fmt::color::crimson) | fmt::emphasis::bold, "Bonjour, {}!n", "world" ); fmt::print(fg(fmt::color::floral_white) | bg(fmt::color::slate_gray) | fmt::emphasis::underline, "Olá, {}!n", "Mundo"); fmt::print(fg(fmt::color::steel_blue) | fmt::emphasis::italic, "你好{}!n", "世界"); }
Sortie sur un terminal moderne avec support Unicode :
Bibliothèque | Méthode | Durée d'exécution, s |
---|---|---|
bibliothèque | imprimer | 0,91 |
libc++ | std :: ostream | 2,49 |
{fmt} 9.1 | fmt :: imprimer | 0,74 |
Format Boost 1.80 | boost::format | 6.26 |
Format folie | folie ::format | 1,87 |
{fmt} est la méthode la plus rapide des méthodes comparées, environ 20 % plus rapide que printf
.
Les résultats ci-dessus ont été générés en créant tinyformat_test.cpp
sur macOS 12.6.1 avec clang++ -O3 -DNDEBUG -DSPEED_TEST -DHAVE_FORMAT
et en prenant le meilleur des trois exécutions. Dans le test, la chaîne de format "%0.10f:%04d:%+g:%s:%p:%c:%%n"
ou équivalent est remplie 2 000 000 de fois avec la sortie envoyée à /dev/null
; pour plus de détails, reportez-vous à la source.
{fmt} est jusqu'à 20 à 30 fois plus rapide que std::ostringstream
et sprintf
sur float
IEEE754 et double
formatage (dtoa-benchmark) et plus rapide que la double conversion et ryu :
Le script bloat-test.py des tests de référence de format compile le temps et la surcharge de code pour les projets non triviaux. Il génère 100 unités de traduction et utilise printf()
ou son alternative cinq fois à chacune pour simuler un projet de taille moyenne. La taille de l'exécutable et le temps de compilation résultants (Apple clang version 15.0.0 (clang-1500.1.0.2.5), macOS Sonoma, le meilleur des trois) sont indiqués dans les tableaux suivants.
Construction optimisée (-O3)
Méthode | Temps de compilation, s | Taille de l'exécutable, KiB | Taille dépouillé, KiB |
---|---|---|---|
imprimer | 1.6 | 54 | 50 |
Flux IOS | 25.9 | 98 | 84 |
fmt 83652df | 4.8 | 54 | 50 |
format minuscule | 29.1 | 161 | 136 |
Format Boost | 55,0 | 530 | 317 |
{fmt} est rapide à compiler et est comparable à printf
en termes de taille binaire par appel (avec une erreur d'arrondi sur ce système).
Construction non optimisée
Méthode | Temps de compilation, s | Taille de l'exécutable, KiB | Taille dépouillé, KiB |
---|---|---|---|
imprimer | 1.4 | 54 | 50 |
Flux IOS | 23.4 | 92 | 68 |
{fmt} 83652df | 4.4 | 89 | 85 |
format minuscule | 24,5 | 204 | 161 |
Format Boost | 36,4 | 831 | 462 |
libc
, lib(std)c++
et libfmt
sont tous liés en tant que bibliothèques partagées pour comparer uniquement la surcharge de la fonction de formatage. Boost Format est une bibliothèque d'en-tête uniquement et ne fournit donc aucune option de liaison.
Veuillez vous référer à Création de la bibliothèque pour obtenir des instructions sur la manière de créer la bibliothèque et d'exécuter les tests unitaires.
Les benchmarks résident dans un référentiel distinct, format-benchmarks, donc pour exécuter les benchmarks, vous devez d'abord cloner ce référentiel et générer des Makefiles avec CMake :
$ git clone --recursive https://github.com/fmtlib/format-benchmark.git $ cd format-benchmark $ cmake .
Ensuite, vous pouvez exécuter le test de vitesse :
$ make speed-test
ou le test de ballonnement :
$ make bloat-test
clang-tidy v18 fournit la vérification modernize-use-std-print qui est capable de convertir les occurrences de printf
et fprintf
en fmt::print
si elle est configurée pour le faire. (Par défaut, il se convertit en std::print
.)
0 AD : un jeu de stratégie en temps réel gratuit, open source et multiplateforme
AMPL/MP : une bibliothèque open source pour la programmation mathématique
FoundationDB d'Apple : un magasin clé-valeur transactionnel open source, distribué
Aseprite : éditeur de sprites animés et outil de pixel art
AvioBook : une suite complète pour les opérations aériennes
Blizzard Battle.net : une plateforme de jeux en ligne
Celestia : visualisation 3D en temps réel de l'espace
Ceph : un système de stockage distribué évolutif
ccache : un cache du compilateur
ClickHouse : un système de gestion de bases de données analytiques
ContextVision : logiciel d'imagerie médicale
Contour : un émulateur de terminal moderne
CUAUV : le véhicule sous-marin autonome de l'Université Cornell
Drake : une boîte à outils de planification, de contrôle et d'analyse pour les systèmes dynamiques non linéaires (MIT)
Envoy : proxy C++ L7 et bus de communication (Lyft)
FiveM : un framework de modification pour GTA V
fmtlog : une bibliothèque de journalisation performante de style fmtlib avec une latence en nanosecondes
Folly : bibliothèque open source de Facebook
GemRB : une implémentation open source portable du moteur Infinity de Bioware
Grand Mountain Adventure : un magnifique jeu de ski et de snowboard en monde ouvert
HarpyWar/pvpgn : réseau de jeu joueur contre joueur avec des ajustements
KBEngine : un moteur de serveur MMOG open source
Keypirinha : un lanceur sémantique pour Windows
Kodi (anciennement xbmc) : logiciel home cinéma
Knuth : nœud complet Bitcoin hautes performances
libunicode : une bibliothèque Unicode C++17 moderne
MariaDB : système de gestion de bases de données relationnelles
Microsoft Verona : langage de programmation de recherche pour la propriété simultanée
MongoDB : base de données documentaires distribuée
MongoDB Smasher : un petit outil pour générer des jeux de données aléatoires
OpenSpace : un framework d'astrovisualisation open source
PenUltima Online (POL) : un serveur MMO, compatible avec la plupart des clients Ultima Online
PyTorch : une bibliothèque d'apprentissage automatique open source
quasardb : une base de données associative distribuée et performante
Quill : bibliothèque de journalisation asynchrone à faible latence
QKW : généraliser l'alias pour simplifier la navigation et exécuter des séquences de commandes de terminal multilignes complexes
redis-cerberus : un proxy de cluster Redis
redpanda : un remplacement Kafka® 10 fois plus rapide pour les systèmes critiques écrits en C++
rpclib : un serveur msgpack-RPC C++ moderne et une bibliothèque client
Salesforce Analytics Cloud : logiciel de business intelligence
Scylla : un magasin de données NoSQL compatible Cassandra qui peut gérer 1 million de transactions par seconde sur un seul serveur
Seastar : un framework C++ open source avancé pour des applications serveur hautes performances sur du matériel moderne
spdlog : bibliothèque de journalisation C++ ultra rapide
Stellar : plateforme financière
Touch Surgery : simulateur de chirurgie
TrinityCore : framework MMORPG open source
? framework userver : framework asynchrone open source avec un riche ensemble d'abstractions et de pilotes de base de données
Windows Terminal : le nouveau terminal Windows
Plus...
Si vous connaissez d'autres projets utilisant cette bibliothèque, veuillez me le faire savoir par e-mail ou en soumettant un problème.
Alors pourquoi encore une autre bibliothèque de formatage ?
Il existe de nombreuses méthodes pour effectuer cette tâche, depuis les méthodes standard comme la famille de fonctions printf et iostreams jusqu'aux bibliothèques Boost Format et FastFormat. La raison pour laquelle j'ai créé une nouvelle bibliothèque est que chaque solution existante que j'ai trouvée présentait de sérieux problèmes ou ne fournissait pas toutes les fonctionnalités dont j'avais besoin.
L'avantage de printf
est qu'il est assez rapide et facilement disponible et fait partie de la bibliothèque standard C. Le principal inconvénient est qu'il ne prend pas en charge les types définis par l'utilisateur. printf
a également des problèmes de sécurité bien qu'ils soient quelque peu atténués avec __attribute__ ((format (printf, ...)) dans GCC. Il existe une extension POSIX qui ajoute les arguments de position requis pour i18n à printf
mais elle ne fait pas partie de C99 et peut ne sera pas disponible sur certaines plateformes.
Le principal problème avec les iostreams est mieux illustré par un exemple :
std::cout << std::setprecision(2) << std::fixed << 1.23456 << "n";
ce qui représente beaucoup de saisie par rapport à printf :
printf("%.2fn", 1.23456);
Matthew Wilson, l'auteur de FastFormat, a appelé cela « l'enfer des chevrons ». Les iostreams ne prennent pas en charge les arguments de position par conception.
La bonne partie est que les iostreams prennent en charge les types définis par l'utilisateur et sont sûrs même si la gestion des erreurs est délicate.
Il s'agit d'une bibliothèque très puissante qui prend en charge à la fois les chaînes de format de type printf
et les arguments de position. Son principal inconvénient est la performance. Selon divers benchmarks, cette méthode est beaucoup plus lente que les autres méthodes considérées ici. Boost Format présente également des temps de construction excessifs et de graves problèmes de surcharge du code (voir Benchmarks).
Il s'agit d'une bibliothèque intéressante, rapide, sûre et dotée d'arguments de position. Cependant, il présente des limites importantes, citant son auteur :
Trois fonctionnalités qui n'ont aucun espoir d'être intégrées dans la conception actuelle sont :
Zéros non significatifs (ou tout autre remplissage non spatial)
Codage octal/hexadécimal
Spécification de largeur/alignement d’exécution
Il est également assez volumineux et dépend fortement de STLSoft, ce qui peut être trop restrictif pour une utilisation dans certains projets.
Ce n'est pas une bibliothèque de formatage mais j'ai décidé de l'inclure ici par souci d'exhaustivité. En tant qu'iostreams, il souffre du problème du mélange de texte textuel et d'arguments. La bibliothèque est assez rapide, mais plus lente pour le formatage des entiers que fmt::format_to
avec la compilation de chaînes de format sur le propre benchmark de Karma, voir Conversion de cent millions d'entiers en chaînes par seconde.
{fmt} est distribué sous licence MIT.
La section Format String Syntax de la documentation est basée sur celle de la documentation du module de chaîne Python. Pour cette raison, la documentation est distribuée sous la licence Python Software Foundation disponible dans doc/python-license.txt. Cela ne s'applique que si vous distribuez la documentation de {fmt}.
La bibliothèque {fmt} est maintenue par Victor Zverovich (vitaut) avec les contributions de nombreuses autres personnes. Voir Contributeurs et versions pour certains noms. Faites-nous savoir si votre contribution n'est pas répertoriée ou est mentionnée de manière incorrecte et nous y remédierons.
Pour signaler un problème de sécurité, veuillez le divulguer dans l'avis de sécurité.
Ce projet est maintenu par une équipe de bénévoles sur une base d'effort raisonnable. Par conséquent, veuillez nous accorder au moins 90 jours pour travailler sur un correctif avant que le problème ne soit rendu public.