如何在C++中重复一次字符串变量?

103 c++

我想在C++中的字符串开头插入'n'个空格(或任何字符串).有没有直接的方法来使用std :: strings或char*字符串?

例如,在Python中你可以做到

>>> "." * 5 + "lolcat"
'.....lolcat'
Run Code Online (Sandbox Code Playgroud)

luk*_*uke 147

std::string(5, '.') + "lolcat"
Run Code Online (Sandbox Code Playgroud)

查看std :: string的构造函数.

  • OP要求重复一个字符串,而不是字符. (66认同)

Com*_*ger 36

没有直接的惯用方法来重复C++中的字符串,相当于Python中的*运算符或Perl中的x运算符.如果你重复一个字符,那么双参数构造函数(如前面的答案所示)效果很好:

std::string(5, '.')
Run Code Online (Sandbox Code Playgroud)

这是一个人为的示例,说明如何使用ostringstream重复字符串n次:

#include <sstream>

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

根据实现,这可能比简单地连接字符串n次稍微有效.


cam*_*amh 17

使用string :: insert的一种形式:

std::string str("lolcat");
str.insert(0, 5, '.');
Run Code Online (Sandbox Code Playgroud)

这将在字符串的开头(位置0)插入"....."(五个点).

  • OP要求重复一个字符串,而不是字符. (10认同)

Pav*_*l P 12

对于 OP std::string 的构造函数提供的示例而言,就足够了:std::string(5, '.'). 但是,如果有人正在寻找一个函数来多次重复 std::string:

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


小智 11

我知道这是一个老问题,但我希望做同样的事情并找到我认为更简单的解决方案.似乎cout使用cout.fill()内置了这个函数,请参阅"完整"解释的链接

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

cout.width(11);
cout.fill('.');
cout << "lolcat" << endl;
Run Code Online (Sandbox Code Playgroud)

输出

.....lolcat
Run Code Online (Sandbox Code Playgroud)

  • 只有点:将最后一行改为......`cout <<""<< endl;` (5认同)

Dan*_*iel 8

正如Jaeger准将提到的那样,我认为其他任何答案都没有真正回答这个问题; 问题是如何重复字符串,而不是字符.

虽然Commodore给出的答案是正确的,但效率很低.这是一个更快的实现,其目的是通过首先以指数方式增长字符串来最小化复制操作和内存分配:

#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;
}
Run Code Online (Sandbox Code Playgroud)

我们还可以定义一个operator*更接近Python版本的东西:

#include <utility>

std::string operator*(std::string str, std::size_t n)
{
    return repeat(std::move(str), n);
}
Run Code Online (Sandbox Code Playgroud)

在我的机器上,这比Commodore给出的实现速度快大约10倍,比一个天真的'追加n - 1倍'解决方案快约2 .

  • 这是一条评论,表明我不相信您声称您的解决方案在效率方面比天真的解决方案好得多。在我的测量中,与简单的解决方案相比,您的代码在小字符串和多次重复时速度更快,但在长字符串和少量重复时速度较慢。您能否提供更详细地解释为什么复制几个大块比复制许多小块性能更高的各种原因的链接?我可以想到分支预测。关于 CPU 缓存,我不确定哪种变体是首选。 (2认同)
  • 这是低效的代码。当 n==0 时,为什么要麻烦 str.clear 和收缩,只需用 RVO 返回一个新的空 std::string{} (2认同)

Ros*_*oto 6

你应该编写自己的流操纵器

cout << multi(5)<<"无论"<<"lolcat";

  • 写一个流操纵器是一种非常复杂的做事非常简单的方式! (14认同)
  • C++是一种非常简单的非常复杂的做事方式. (10认同)

sor*_*abz 6

ITNOA

您可以使用 C++ 函数来执行此操作。

 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();
 }
Run Code Online (Sandbox Code Playgroud)

  • “ITNOA”到底是什么意思?在网上找不到任何参考。 (5认同)