c++ - titel - title tag länge 2018




Wie verkette ich eine std:: string und eine int? (19)

Als eine Qt-bezogene Frage zugunsten dieser Frage geschlossen wurde, hier ist, wie es mit Qt zu tun ist:

QString string = QString("Some string %1 with an int somewhere").arg(someIntVariable);
string.append(someOtherIntVariable);

Die String-Variable hat jetzt den Wert von someIntVariable anstelle von% 1 und den Wert von someOtherIntVariable am Ende.

Ich dachte, das wäre wirklich einfach, aber es bringt einige Schwierigkeiten mit sich. Wenn ich habe

std::string name = "John";
int age = 21;

Wie kombiniere ich sie, um eine einzige Saite "John21" ?


Der std :: ostringstream ist eine gute Methode, aber manchmal kann dieser zusätzliche Trick nützlich sein, wenn man die Formatierung in einen Einzeiler umwandelt:

#include <sstream>
#define MAKE_STRING(tokens) /****************/ \
    static_cast<std::ostringstream&>(          \
        std::ostringstream().flush() << tokens \
    ).str()                                    \
    /**/

Jetzt können Sie Strings wie folgt formatieren:

int main() {
    int i = 123;
    std::string message = MAKE_STRING("i = " << i);
    std::cout << message << std::endl; // prints: "i = 123"
}

Dies ist der einfachste Weg:

string s = name + std::to_string(age);

Eine alternative Lösung für Leute wie mich vorschlagen, die möglicherweise keinen Zugriff auf C ++ 11 und zusätzliche Bibliotheken / Header wie Boost haben. Eine einfache Umwandlung funktioniert folgendermaßen:

Beispiel die Zahl ist 4, um 3 in ASCII umzuwandeln können wir einfach den Code verwenden:
char a = '0' + 4

Dies speichert sofort 4 als Zeichen in einem.

Von hier aus können wir einfach a mit dem Rest der Zeichenkette verketten.


Es gibt eine Funktion, die ich geschrieben habe, die Parameter die int-Zahl aufnimmt und in ein String-Literal umwandelt. Diese Funktion hängt von einer anderen Funktion ab, die eine einzelne Ziffer in ihr entsprechendes Zeichen konvertiert:

char intToChar ( int num)
{
    if ( num < 10 && num >= 0)
    {
        return num + 48; 
        //48 is the number that we add to an integer number to have its character equivalent (see the unsigned ASCII table)
    }
    else
    {
        return '*';
    }
}

string intToString ( int num)
{
    int digits = 0, process, single;
    string numString;
    process = num;

    //The following process the number of digits in num
    while ( process != 0)
    {
        single  = process % 10; // single now hold the rightmost portion of the int
        process = (process - single)/10;
        // take out the rightmost number of the int ( it's a zero in this portion of the int), then divide it by 10
        // The above combinasion eliminates the rightmost portion of the int
        digits ++;
    }

    process = num;

    //Fill the numString with '*' times digits
    for ( int i = 0; i < digits; i++)
    {
        numString += '*';
    }


    for ( int i = digits-1; i >= 0; i-- )
    {
        single = process % 10;
        numString[i] = intToChar ( single);
        process = ( process - single) / 10;
    }

    return numString;
}

Es gibt mehrere Optionen, die verwendet werden können, um eine Ganzzahl (oder ein anderes numerisches Objekt) mit einer Zeichenfolge zu verketten. Es ist Boost.Format

#include <boost/format.hpp>
#include <string>
int main()
{
    using boost::format;

    int age = 22;
    std::string str_age = str(format("age is %1%") % age);
}

und Karma von Boost.Spirit (v2)

#include <boost/spirit/include/karma.hpp>
#include <iterator>
#include <string>
int main()
{
    using namespace boost::spirit;

    int age = 22;
    std::string str_age("age is ");
    std::back_insert_iterator<std::string> sink(str_age);
    karma::generate(sink, int_, age);

    return 0;
}

Boost.Spirit Karma behauptet, eine der schnellsten Optionen für die Umwandlung von Ganzzahl in Zeichenkette zu sein .


Gemeinsame Antwort: itoa()

Das ist schlecht. itoa ist nicht Standard, wie here .


Herb Sutter hat einen guten Artikel zu diesem Thema: "The String Formatters of Manor Farm" . Er behandelt Boost::lexical_cast , std::stringstream , std::strstream (was veraltet ist) und sprintf vs. snprintf .


Ich habe nicht genug Karma, um etwas zu kommentieren (geschweige denn zu editieren), aber Jay's Post (derzeit der mit der besten Wahl bei 27) enthält einen Fehler. Dieser Code:

std::stringstream ss;
ss << age;
std::cout << name << ss.str() << std::endl;

Löst das angegebene Problem des Erstellens einer Zeichenfolge, die aus einer verketteten Zeichenfolge und Ganzzahl besteht, nicht. Ich glaube Jay meinte etwas mehr so:

std::stringstream ss;
ss << name;
ss << age;
std::cout << "built string: " << ss.str() << std::endl;

Die letzte Zeile dient nur zum Drucken des Ergebnisses und zeigt, wie auf die letzte verkettete Zeichenfolge zugegriffen wird.


Im Folgenden finden Sie eine Implementierung zum Anfügen eines Int an eine Zeichenfolge mithilfe der Facetten zum Analysieren und Formatieren aus der IOStreams-Bibliothek.

#include <iostream>
#include <locale>
#include <string>

template <class Facet>
struct erasable_facet : Facet
{
    erasable_facet() : Facet(1) { }
    ~erasable_facet() { }
};

void append_int(std::string& s, int n)
{
    erasable_facet<std::num_put<char,
                                std::back_insert_iterator<std::string>>> facet;
    std::ios str(nullptr);

    facet.put(std::back_inserter(s), str,
                                     str.fill(), static_cast<unsigned long>(n));
}

int main()
{
    std::string str = "ID: ";
    int id = 123;

    append_int(str, id);

    std::cout << str; // ID: 123
}

In alphabetischer Reihenfolge:

std::string name = "John";
int age = 21;
std::string result;

// 1. with Boost
result = name + boost::lexical_cast<std::string>(age);

// 2. with C++11
result = name + std::to_string(age);

// 3. with FastFormat.Format
fastformat::fmt(result, "{0}{1}", name, age);

// 4. with FastFormat.Write
fastformat::write(result, name, age);

// 5. with the {fmt} library
result = fmt::format("{}{}", name, age);

// 6. with IOStreams
std::stringstream sstm;
sstm << name << age;
result = sstm.str();

// 7. with itoa
char numstr[21]; // enough to hold all numbers up to 64-bits
result = name + itoa(age, numstr, 10);

// 8. with sprintf
char numstr[21]; // enough to hold all numbers up to 64-bits
sprintf(numstr, "%d", age);
result = name + numstr;

// 9. with STLSoft's integer_to_string
char numstr[21]; // enough to hold all numbers up to 64-bits
result = name + stlsoft::integer_to_string(numstr, 21, age);

// 10. with STLSoft's winstl::int_to_string()
result = name + winstl::int_to_string(age);

// 11. With Poco NumberFormatter
result = name + Poco::NumberFormatter().format(age);
  1. ist sicher, aber langsam; benötigt Boost (nur Header); meisten / alle Plattformen
  2. ist sicher, erfordert C ++ 11 ( to_string() ist bereits in #include <string> )
  3. ist sicher und schnell; erfordert FastFormat , das kompiliert werden muss; meisten / alle Plattformen
  4. ist sicher und schnell; erfordert FastFormat , das kompiliert werden muss; meisten / alle Plattformen
  5. ist sicher und schnell; benötigt die Bibliothek {fmt} , die entweder kompiliert oder in einem Nur-Kopf-Modus verwendet werden kann; meisten / alle Plattformen
  6. sicher, langsam und ausführlich; benötigt #include <sstream> (aus Standard C ++)
  7. ist brüchig (Sie müssen einen ausreichend großen Puffer bereitstellen), schnell und ausführlich; itoa () ist eine nicht standardmäßige Erweiterung und nicht garantiert für alle Plattformen verfügbar
  8. ist brüchig (Sie müssen einen ausreichend großen Puffer bereitstellen), schnell und ausführlich; benötigt nichts (ist Standard C ++); alle Plattformen
  9. ist spröde (Sie müssen einen ausreichend großen Puffer bereitstellen), wahrscheinlich die schnellstmögliche Konvertierung , ausführlich; erfordert STLSoft (nur Header); meisten / alle Plattformen
  10. safe-ish (Sie verwenden nicht mehr als einen Aufruf von int_to_string () in einer einzigen Anweisung), schnell; erfordert STLSoft (nur Header); Nur Windows
  11. ist sicher, aber langsam; benötigt Boost ; meisten / alle Plattformen

Mit der Bibliothek {fmt} :

auto result = fmt::format("{}{}", name, age);

Eine Untergruppe der Bibliothek wird für die Standardisierung als P0645-Textformatierung vorgeschlagen. Wenn dies akzeptiert wird, wird das obige:

auto result = std::format("{}{}", name, age);

Haftungsausschluss : Ich bin der Autor der {fmt} -Bibliothek.


Sie können int mit dem unten angegebenen einfachen Trick in eine Zeichenkette überführen, beachten Sie jedoch, dass dies nur funktioniert, wenn die ganze Zahl aus einer einzelnen Ziffer besteht, andernfalls addieren Sie die ganze Zahl Ziffer um Zahl zu dieser Zeichenkette.

string name = "John";
int age = 5;
char temp=5+'0';
name=name+temp;
cout<<name<<endl;

Output:-  John5

Wenn Sie + für die Verkettung von allem, das einen Ausgabeoperator verwendet, verwenden möchten, können Sie eine Vorlagenversion von operator+ bereitstellen:

template <typename L, typename R> std::string operator+(L left, R right) {
  std::ostringstream os;
  os << left << right;
  return os.str();
}

Dann können Sie Ihre Verkettungen einfach schreiben:

std::string foo("the answer is ");
int i = 42;
std::string bar(foo + i);    
std::cout << bar << std::endl;

Ausgabe:

the answer is 42

Dies ist nicht der effizienteste Weg, aber Sie brauchen nicht den effizientesten Weg, es sei denn, Sie machen viele Verkettungen innerhalb einer Schleife.


Wenn Sie C ++ 11 haben, können Sie std::to_string .

Beispiel:

std::string name = "John";
int age = 21;

name += std::to_string(age);

std::cout << name;

Ausgabe:

John21

Wenn Sie MFC verwenden, können Sie einen CString verwenden

CString nameAge = "";
nameAge.Format("%s%d", "John", 21);

Managed C ++ hat auch einen String-Formatierer .


#include <iostream>
#include <string>
#include <sstream>
using namespace std;
string itos(int i) // convert int to string
{
    stringstream s;
    s << i;
    return s.str();
}

Schamlos gestohlen von http://www.research.att.com/~bs/bs_faq2.html .


#include <sstream>

template <class T>
inline std::string to_string (const T& t)
{
   std::stringstream ss;
   ss << t;
   return ss.str();
}

Dann würde Ihre Verwendung in etwa so aussehen

   std::string szName = "John";
   int numAge = 23;
   szName += to_string<int>(numAge);
   cout << szName << endl;

Googled [und getestet: p]


std::ostringstream o;
o << name << age;
std::cout << o.str();




stdstring