Pourquoi C++ est le langage idéal pour les utilitaires CLI ?
Quand il s'agit de créer des utilitaires CLI en C++, de nombreux développeurs haussent les épaules : "Pourquoi ? Il y a Python, Go, Rust". Mais regardons la vérité en face. Si vous avez besoin d'une vitesse fulgurante, d'une consommation mémoire minimale et d'un contrôle total sur le matériel — C++ est imbattable. Les administrateurs système, les ingénieurs DevOps et les développeurs de systèmes embarqués écrivent encore leurs outils console dans ce langage. Et vous savez quoi ? C'est la bonne décision.
Aujourd'hui, nous allons détailler la création d'un utilitaire CLI en C++ à partir de zéro — de l'analyse des arguments à la compilation du binaire. Vous apprendrez à écrire un véritable outil utile, que vous n'aurez pas honte de publier sur GitHub. C'est parti.
Outillage : ce dont nous avons besoin
Pour travailler confortablement, nous aurons besoin de :
- Compilateur C++17/20 — GCC (MinGW sur Windows) ou Clang. Personnellement, je recommande GCC 11+.
- Éditeur de texte ou IDE — VS Code avec le plugin C++, CLion, ou même Vim (pour les puristes).
- CMake — pour une compilation facile. On pourrait utiliser Makefile, mais CMake est la norme moderne.
- Git — impossible sans contrôle de version.
Nous aurons également besoin d'une bibliothèque pour analyser les arguments de la ligne de commande. Nous ne réinventerons pas la roue et prendrons la légendaire getopt (présente sur les systèmes POSIX) ou nous écrirons notre propre analyseur minimaliste. La deuxième option est encore plus intéressante — vous comprendrez comment cela fonctionne "sous le capot".
Structure du projet
Avant d'écrire du code, définissons ce que nous créons exactement. Que ce soit l'utilitaire fileutils — un outil console pour travailler avec les fichiers. Il saura faire :
- Compter le nombre de lignes, de mots et de caractères dans un fichier (équivalent de
wc). - Rechercher une chaîne selon un motif (équivalent minimal de
grep). - Afficher l'aide (
--help).
Structure des dossiers :
fileutils/├── src/│ ├── main.cpp│ ├── parser.cpp│ └── parser.h├── CMakeLists.txt└── README.mdÉtape 1 : Analyseur d'arguments personnalisé
Écrivons un analyseur simple mais fonctionnel. Il traitera les drapeaux longs (--lines, --words) et les arguments positionnels (nom du fichier).
Fichier parser.h
#ifndef PARSER_H#define PARSER_H
#include <string>#include <vector>#include <map>
struct Args { bool show_lines = false; bool show_words = false; bool show_chars = false; std::string pattern; std::vector<std::string> files;};
Args parse_args(int argc, char* argv[]);
#endifFichier parser.cpp
#include "parser.h"#include <iostream>
Args parse_args(int argc, char* argv[]) { Args args; for (int i = 1; i < argc; ++i) { std::string arg = argv[i]; if (arg == "--help" || arg == "-h") { std::cout << "Usage: fileutils [OPTIONS] FILE..." << "Options:" << " --lines, -l Afficher le nombre de lignes" << " --words, -w Afficher le nombre de mots" << " --chars, -c Afficher le nombre de caractères" << " --search MOT Rechercher un motif" << " --help, -h Afficher cette aide"; exit(0); } else if (arg == "--lines" || arg == "-l") { args.show_lines = true; } else if (arg == "--words" || arg == "-w") { args.show_words = true; } else if (arg == "--chars" || arg == "-c") { args.show_chars = true; } else if (arg == "--search" && i + 1 < argc) { args.pattern = argv[++i];