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'

248voto

luke Points 16255

Dans le cas particulier de la répétition d'un seul caractère, on peut utiliser std::string(size_type count, CharT ch) :

std::string(5, '.') + "lolcat"

On ne peut pas l'utiliser pour répéter des chaînes de caractères multiples.

51voto

Commodore Jaeger Points 11949

Il n'existe pas de moyen idiomatique direct de répéter des chaînes de caractères en C++ qui soit équivalent à la fonction * en Python ou l'opérateur x en Perl. Si vous répétez un seul caractère, le constructeur à deux arguments (comme suggéré par les réponses précédentes) fonctionne bien :

std::string(5, '.')

Il s'agit d'un exemple artificiel de la façon dont vous pouvez utiliser un ostringstream pour répéter une chaîne n fois :

#include <sstream>

std::string repeat(int n) {
    std::ostringstream os;
    for(int i = 0; i < n; i++)
        os << "repeat";
    return os.str();
}

Selon l'implémentation, cela peut être légèrement plus efficace que de simplement concaténer la chaîne n fois.

22voto

camh Points 13169

Utilisez l'une des formes de string::insert :

std::string str("lolcat");
str.insert(0, 5, '.');

Ceci va insérer "....." (cinq points) au début de la chaîne (position 0).

15voto

Pavel Points 1715

Pour les besoins de l'exemple fourni par l'OP, le ctor de std::string est suffisant : std::string(5, '.') . Cependant, si quelqu'un cherche une fonction pour répéter std::string plusieurs fois :

std::string repeat(const std::string& input, unsigned num)
{
    std::string ret;
    ret.reserve(input.size() * num);
    while (num--)
        ret += input;
    return ret;
}

14voto

Daniel Points 958

Comme le Commodore Jaeger y a fait allusion, je ne pense pas que les autres réponses répondent réellement à cette question ; la question demande comment répéter une chaîne, pas un caractère.

Bien que la réponse donnée par Commodore soit correcte, elle est assez inefficace. Voici une implémentation plus rapide, l'idée est de minimiser les opérations de copie et les allocations de mémoire en faisant d'abord croître la chaîne de manière exponentielle :

#include <string>
#include <cstddef>

std::string repeat(std::string str, const std::size_t n)
{
    if (n == 0) {
        str.clear();
        str.shrink_to_fit();
        return str;
    } else if (n == 1 || str.empty()) {
        return str;
    }
    const auto period = str.size();
    if (period == 1) {
        str.append(n - 1, str.front());
        return str;
    }
    str.reserve(period * n);
    std::size_t m {2};
    for (; m < n; m *= 2) str += str;
    str.append(str.c_str(), (n - (m / 2)) * period);
    return str;
}

Nous pouvons également définir un operator* pour obtenir quelque chose de plus proche de la version Python :

#include <utility>

std::string operator*(std::string str, std::size_t n)
{
    return repeat(std::move(str), n);
}

Sur ma machine, cela est environ 10 fois plus rapide que l'implémentation donnée par Commodore, et environ 2 fois plus rapide qu'une implémentation naïve. "ajouter n - 1 fois solution.

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