web-dev-qa-db-fra.com

C++ std :: transform () et toupper () .. pourquoi cela échoue-t-il?

J'ai 2 std :: string. Je veux juste, étant donné la chaîne d'entrée:

  1. capitaliser chaque lettre
  2. assigne la lettre en majuscule à la chaîne de sortie.

Comment ça marche?

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

mais cela ne fonctionne pas (entraîne un blocage du programme)?

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

parce que cela fonctionne (au moins sur la même chaîne:

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

Il n'y a pas d'espace dans out. Les algorithmes C++ ne développent pas automatiquement leurs conteneurs cibles. Vous devez soit créer l'espace vous-même, soit utiliser un adaptateur d'insertion.

Pour créer de l'espace dans out, procédez comme suit:

out.resize(s.length());

[edit] Une autre option consiste à créer la chaîne de sortie de taille correcte avec ce constructeur.

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

41
hrnt

Je dirais que l'itérateur renvoyé par out.begin() n'est pas valide après quelques incréments pour la chaîne vide. Après le premier ++, c'est ==out.end(), le comportement après le prochain incrément est indéfini.

Après tout cela, exactement ce à quoi sert itérateur.

2

Thats le sens d'un backinserter: Il insère éléments dans un conteneur. En utilisant begin (), vous passez un itérateur à un conteneur vide et modifiez des itérateurs non valides.

Je suis désolé - mes modifications ont interféré avec vos commentaires. J'ai d'abord posté quelque chose de mal accidentellement.

0
RED SOFT ADAIR