2011-06-22 5 views
0

J'essaie d'utiliser std::copy pour copier à partir de deux itérateurs différents. Mais au cours de l'exécution, ces deux itérateurs peuvent pointer vers le même emplacement. Pourquoi dans cette situation, ils ne copient pas les caractères uniques.copier un seul caractère en utilisant std :: copy

std::string str1 = "ABC"; 
std::string::iterator itr1 = str1.begin(); 
std::string::iterator itr2 = str1.begin(); 
std::string result; 
std::copy(itr1,itr2,result.begin()); 
+0

Notez que 'result' doit déjà avoir suffisamment de place pour contenir les caractères que vous voulez copier. Vous devez donc soit le créer avec la longueur 1, soit le redimensionner à cette longueur, soit utiliser un inserteur arrière. – sbi

Répondre

7

La limite droite de la plage dans STL n'est pas inclusive. Si vous lui donnez le même itérateur deux fois, le résultat est une plage vide. Vous voulez ceci:

std::copy(itr1,itr2+1,result.begin()); 

Mais, méfiez-vous que vous écrivez à un emplacement sans mémoire réservée, ce qui est un comportement non défini. Vous devez utiliser un back_insert_iterator

std::copy(itr1,itr2 + 1, std::back_inserter(result)); 
+0

Ou encore plus simple: 'std :: string (itr1, itr2 + 1)' – ereOn

+1

@ereOn: Vous voulez dire 'std :: string result (itr, itr2 + 1)'? :) –

2

Ecrire:

result.resize(1); //it must have some size 
std::copy(itr1,itr2 + 1,result.begin()); 

Ou mieux encore.

//no need to resize now! 
std::copy(itr1,itr2 + N, std::back_inserter(result)); 

N est le nombre de caractères que vous souhaitez copier sur result.

1

Dans votre situation, vous pouvez simplement faire:

std::string result(itr1, itr1 + 1); 

Depuis std::string a a constructor qui prend deux itérateurs pour copier son contenu à partir.

Maintenant, pour les explications:

std::copy(itr1, itr2, res) copie tous les éléments à partir de itr1 et d'arrêt juste avantitr2 un emplacement spécifié par l'res.

Autrement dit, si itr1 == itr2 il n'y a pas de "trou" entre les deux itérateurs et que rien n'est copié.

C'est pourquoi l'itérateur end() pointe généralement vers dernier élément d'une collection.


Considérons le vecteur suivant, vec, qui dispose de 3 éléments:

1, 2, 3, X 
^  ^
|  | 
|  \-- end() (X indicates a slot past the last element) 
\----------- begin() 

C'est, si vous utilisez std::copy() avec begin() et end() vous copierez en fait tous les éléments de vec.

0

Le second paramètre à copy() est l'élément après le dernier copié; str1.end() pointerait après le dernier caractère, pas avant. Votre appel demande que 0 caractère soit copié, et c'est ce que vous obtenez. Vous pouvez avancer itr2 par un avant de passer l'appel.

Questions connexes