166 votes

Comment répéter une chaîne de caractères un nombre variable de fois en C++ ?

Je veux insérer "n" espaces (ou n'importe quelle chaîne) au début d'une chaîne en C++. Existe-t-il un moyen direct de le faire en utilisant std::strings ou char* strings ?

Par exemple, en Python, vous pourriez simplement faire

>>> "." * 5 + "lolcat"
'.....lolcat'

13voto

Ian Points 31

Je sais que c'est une vieille question, mais je cherchais à faire la même chose et j'ai trouvé ce que je pense être une solution plus simple. Il semble que cout ait cette fonction intégrée dans cout.fill(), voir le lien pour une explication "complète".

http://www.java-samples.com/showtutorial.php?tutorialid=458

cout.width(11);
cout.fill('.');
cout << "lolcat" << endl;

sorties

.....lolcat

10voto

sorosh_sabz Points 339

Vous pouvez utiliser une fonction C++ pour ce faire :

 std::string repeat(const std::string& input, size_t num)
 {
    std::ostringstream os;
    std::fill_n(std::ostream_iterator<std::string>(os), num, input);
    return os.str();
 }

7voto

Roskoto Points 588

Vous devriez écrire votre propre manipulateur de flux

3voto

claytonjwong Points 207

Voici un exemple de la chaîne de caractères "abc". repeated 3 fois :

#include <iostream>
#include <sstream>
#include <algorithm>
#include <string>
#include <iterator>

using namespace std;

int main() {
    ostringstream repeated;
    fill_n(ostream_iterator<string>(repeated), 3, string("abc"));
    cout << "repeated: " << repeated.str() << endl;  // repeated: abcabcabc
    return 0;
}

1voto

Matthew M. Points 69

@Daniel a fourni une implémentation qui est significativement plus rapide que les autres réponses dans sa branche d'exécution primaire (où n > 1 et str n'est pas vide). Cependant, les cas limites sont traités de manière beaucoup plus inefficace qu'ils ne pourraient l'être.

Cette mise en œuvre corrige ces problèmes :

#include <string>
#include <cstddef>

std::string repeat(size_t n, const std::string& str) {
    if (n == 0 || str.empty()) return {};
    if (n == 1) return str;
    const auto period = str.size();
    if (period == 1) return std::string(n, str.front());

    std::string ret(str);
    ret.reserve(period * n);
    std::size_t m {2};
    for (; m < n; m *= 2) ret += ret;
    ret.append(ret.c_str(), (n - (m / 2)) * period);
    return ret;
}

Une comparaison des deux implémentations sur quick-bench.com montre les différences suivantes dans ces cas particuliers. Clang 13.0 est le premier chiffre et GCC 10.3 le second. Optimisation -O3 dans tous les cas.

  • Pour n == 0, cette implémentation est (9x / 11x) plus rapide.
  • Pour str.empty() == true, il est (2,4x / 3,4x) plus rapide.
  • Pour n == 1 et str.size() > 1, il est (2.1x / 1.4x) plus rapide.
  • Et pour str.size() == 1, il est (1,3x / 1,2x) plus rapide.

Le problème avec l'implémentation originale se résume à passer str dans la fonction par valeur. Ceci invoque une copie de str à chaque appel à repeat qui est inutile dans certains cas particuliers, notamment lorsque n == 0.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X