wake-up-neo.net

C++ std :: transform () und toupper (). Warum schlägt dies fehl?

Ich habe 2 std :: string. Ich möchte nur, angesichts der Eingabezeichenfolge:

  1. schreibe jeden Buchstaben in Großbuchstaben
  2. weisen Sie der Ausgabezeichenfolge den Großbuchstaben zu.

Wie kommt es, dass dies funktioniert:

  std::string s="hello";
  std::string out;
  std::transform(s.begin(), s.end(), std::back_inserter(out), std::toupper);

aber das tut es nicht (führt zu einem Programmabsturz)?

  std::string s="hello";
  std::string out;
  std::transform(s.begin(), s.end(), out.begin(), std::toupper);

weil das funktioniert (zumindest mit der gleichen Zeichenfolge:

  std::string s="hello";
  std::string out;
  std::transform(s.begin(), s.end(), s.begin(), std::toupper);
27
sivabudh

In out ist kein Leerzeichen. C++ - Algorithmen vergrößern ihre Zielcontainer nicht automatisch. Sie müssen den Platz entweder selbst schaffen oder einen Inserter-Adapter verwenden.

Gehen Sie folgendermaßen vor, um in out Platz zu schaffen:

out.resize(s.length());

[edit] Eine andere Möglichkeit ist, mit diesem Konstruktor den Ausgabe-String mit der richtigen Größe zu erstellen.

std::string out(s.length(), 'X');

41
hrnt

Ich würde sagen, dass der von out.begin() zurückgegebene Iterator nach ein paar Inkrementen für die leere Zeichenfolge nicht mehr gültig ist. Nach dem ersten ++ ist es ==out.end(), dann ist das Verhalten nach dem nächsten Inkrement undefiniert.

Nach all dem ist genau das, wofür Insert-Iterator ist.

Das ist der Sinn eines Backinserter: Er fügt Elemente in einen Container ein. Mit begin () übergeben Sie einen Iterator an einen leeren Container und ändern ungültige Iteratoren.

Es tut mir leid - meine Änderungen haben Ihre Kommentare beeinträchtigt. Ich habe zuerst versehentlich etwas falsches gepostet.

0
RED SOFT ADAIR