webentwicklung-frage-antwort-db.com.de

String.Format-Alternative in C ++

Ich habe nicht viel Erfahrung mit C++. Eher habe ich mehr in C # gearbeitet und wollte meine Frage stellen, indem ich bezog, was ich dort getan hätte. Ich muss ein bestimmtes Format der Zeichenfolge generieren, das ich an eine andere Funktion übergeben muss. In C # hätte ich die Zeichenfolge problemlos mit dem folgenden einfachen Code generiert.

string a = "test";
string b = "text.txt";
string c = "text1.txt";

String.Format("{0} {1} > {2}", a, b, c);

Durch Generieren eines solchen obigen Strings sollte es mir möglich sein, dies in system() zu übergeben. system akzeptiert jedoch nur char*

Ich bin auf Win32 C++ (Nicht C++/CLI) und kann boost nicht verwenden, da es zu viel Einschluss aller Dateien für ein Projekt beinhalten würde, das selbst sehr klein ist. Etwas wie sprintf() erscheint mir nützlich, aber sprintf akzeptiert string nicht als a, b und c ] _ Parameter. Irgendwelche Vorschläge, wie ich diese formatierten Zeichenfolgen generieren kann, um sie in meinem Programm an das System zu übergeben?

27
user1240679

Sie können sprintf in Kombination mit std::string.c_str() verwenden.

c_str() gibt einen const char* zurück und arbeitet mit 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;

oder Sie können ein vorab zugewiesenes Array char verwenden, wenn Sie die Größe kennen:

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() );
7
Luchian Grigore

Der C++ - Weg wäre die Verwendung eines std::stringstream Objekt als:

std::stringstream fmt;
fmt << a << " " << b << " > " << c;

Der C-Weg wäre, sprintf zu verwenden.

Der C-Weg ist schwer zu finden, da:

  • Es ist unsicher
  • Benötigt Pufferverwaltung

Natürlich möchten Sie möglicherweise auf die C-Methode zurückgreifen, wenn die Leistung ein Problem darstellt (stellen Sie sich vor, Sie erstellen Millionen kleiner stringstream Objekte mit fester Größe und werfen sie dann weg).

34
dirkgently

Der Vollständigkeit halber können Sie 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";
}

Oder (in diesem Fall) std::strings eigene Funktionen zur Verkettung von Zeichenfolgen:

#include <iostream>
#include <string>

int main() {
    std::string a = "a", b = "b", c = "c";
    std::string str = a + " " + b + " > " + c;
    std::cout << str << "\n";
}

Als Referenz:


Wenn Sie wirklich den C-Weg gehen wollen. Hier sind Sie ja:

#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";
}

Als Referenz:


Dann gibt es noch die Boost Format Library . Für Ihr Beispiel:

#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";
}
20
moooeeeep

Zusätzlich zu den von anderen vorgeschlagenen Optionen kann ich die fmt-Bibliothek empfehlen, die eine Zeichenfolgenformatierung ähnlich str.format in Python implementiert und String.Format in C #. Hier ein Beispiel:

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);

Haftungsausschluss: Ich bin der Autor dieser Bibliothek.

13
vitaut

Sie können die Zeichenfolgen einfach verketten und eine Befehlszeile erstellen.

std::string command = a + ' ' + b + " > " + c;
system(command.c_str());

Sie benötigen dafür keine zusätzlichen Bibliotheken.

2
Bo Persson

Der Vollständigkeit halber wäre der Boost-Weg boost::format

cout << boost::format("%s %s > %s") % a % b % c;

Treffen Sie Ihre Wahl. Die Boost-Lösung bietet den Vorteil der Typensicherheit mit dem sprintf -Format (für diejenigen, die das << Syntax etwas klobig).

2
Shep

Wie bereits erwähnt, verwendet der C++ - Weg Stringstreams.

#include <sstream>

string a = "test";
string b = "text.txt";
string c = "text1.txt";

std::stringstream ostr;
ostr << a << " " << b << " > " << c;

Beachten Sie, dass Sie den C-String wie folgt aus dem String-Stream-Objekt abrufen können.

std::string formatted_string = ostr.str();
const char* c_str = formatted_string.c_str();
1
user1359278