Je n'ai pas beaucoup d'expérience avec C++. J'ai plutôt travaillé plus en C # et donc, je voulais poser ma question en rapport avec ce que j'aurais fait là-dedans. Je dois générer un format spécifique de la chaîne, que je dois transmettre à une autre fonction. En C #, j'aurais facilement généré la chaîne via le code simple ci-dessous.
string a = "test";
string b = "text.txt";
string c = "text1.txt";
String.Format("{0} {1} > {2}", a, b, c);
En générant une telle chaîne ci-dessus, je devrais pouvoir passer ceci dans system()
. Cependant, system
accepte uniquement char*
Je suis sur Win32 C++
(Pas C++/CLI), et je ne peux pas utiliser boost
car cela inclurait trop d'inclusion de tous les fichiers pour un projet qui lui-même est très petit. Quelque chose comme sprintf()
me semble utile, mais sprintf
n'accepte pas string
comme a
, b
et c
paramètres. Des suggestions sur la façon dont je peux générer ces chaînes formatées pour les transmettre au système dans mon programme?
Vous pouvez utiliser sprintf
en combinaison avec std::string.c_str()
.
c_str()
renvoie un const char*
et fonctionne avec sprintf
:
string a = "test";
string b = "text.txt";
string c = "text1.txt";
char* x = new char[a.length() + b.length() + c.length() + 32];
sprintf(x, "%s %s > %s", a.c_str(), b.c_str(), c.c_str() );
string str = x;
delete[] x;
ou vous pouvez utiliser un tableau char
pré-alloué si vous connaissez la taille:
string a = "test";
string b = "text.txt";
string c = "text1.txt";
char x[256];
sprintf(x, "%s %s > %s", a.c_str(), b.c_str(), c.c_str() );
La manière C++ serait d'utiliser un std::stringstream
objet comme:
std::stringstream fmt;
fmt << a << " " << b << " > " << c;
La manière C serait d'utiliser sprintf
.
La voie C est difficile à obtenir car:
Bien sûr, vous voudrez peut-être vous replier sur la voie C si les performances sont un problème (imaginez que vous créez des millions de petits objets stringstream
de taille fixe, puis les jetez).
Par souci d'exhaustivité, vous pouvez utiliser std::stringstream
:
#include <iostream>
#include <sstream>
#include <string>
int main() {
std::string a = "a", b = "b", c = "c";
// apply formatting
std::stringstream s;
s << a << " " << b << " > " << c;
// assign to std::string
std::string str = s.str();
std::cout << str << "\n";
}
Ou (dans ce cas) std::string
possède ses propres capacités de concaténation de chaînes:
#include <iostream>
#include <string>
int main() {
std::string a = "a", b = "b", c = "c";
std::string str = a + " " + b + " > " + c;
std::cout << str << "\n";
}
Pour référence:
Si vous voulez vraiment aller dans le sens C. Vous voilà:
#include <iostream>
#include <string>
#include <vector>
#include <cstdio>
int main() {
std::string a = "a", b = "b", c = "c";
const char fmt[] = "%s %s > %s";
// use std::vector for memory management (to avoid memory leaks)
std::vector<char>::size_type size = 256;
std::vector<char> buf;
do {
// use snprintf instead of sprintf (to avoid buffer overflows)
// snprintf returns the required size (without terminating null)
// if buffer is too small initially: loop should run at most twice
buf.resize(size+1);
size = std::snprintf(
&buf[0], buf.size(),
fmt, a.c_str(), b.c_str(), c.c_str());
} while (size+1 > buf.size());
// assign to std::string
std::string str = &buf[0];
std::cout << str << "\n";
}
Pour référence:
Ensuite, il y a Boost Format Library . Pour votre exemple:
#include <iostream>
#include <string>
#include <boost/format.hpp>
int main() {
std::string a = "a", b = "b", c = "c";
// apply format
boost::format fmt = boost::format("%s %s > %s") % a % b % c;
// assign to std::string
std::string str = fmt.str();
std::cout << str << "\n";
}
En plus des options suggérées par d'autres, je peux recommander la bibliothèque fmt qui implémente un formatage de chaîne similaire à str.format
in Python et String.Format
en C #. Voici un exemple:
std::string a = "test";
std::string b = "text.txt";
std::string c = "text1.txt";
std::string result = fmt::format("{0} {1} > {2}", a, b, c);
Avertissement: je suis l'auteur de cette bibliothèque.
Vous pouvez simplement concaténer les chaînes et créer une ligne de commande.
std::string command = a + ' ' + b + " > " + c;
system(command.c_str());
Vous n'avez pas besoin de bibliothèques supplémentaires pour cela.
Pour être complet, la manière la plus rapide serait d'utiliser boost::format
cout << boost::format("%s %s > %s") % a % b % c;
Faites votre choix. La solution boost a l'avantage de la sécurité de type avec le format sprintf
(pour ceux qui trouvent le <<
syntaxe un peu maladroite).
Comme déjà mentionné, la méthode C++ utilise des flux de chaînes.
#include <sstream>
string a = "test";
string b = "text.txt";
string c = "text1.txt";
std::stringstream ostr;
ostr << a << " " << b << " > " << c;
Notez que vous pouvez obtenir la chaîne C à partir de l'objet de flux de chaîne comme ceci.
std::string formatted_string = ostr.str();
const char* c_str = formatted_string.c_str();