21

What do I have to do so that when I

string s = ".";

If I do

cout << s * 2;

Will it be the same as

cout << "..";

?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
skittles sour
  • 479
  • 1
  • 4
  • 7
  • 8
    it will not even compile – Andrew Aug 07 '12 at 09:44
  • 13
    Why don't you give it a try and see for yourself? – chessweb Aug 07 '12 at 09:46
  • Better if you ask how to make it works – janisz Aug 07 '12 at 09:47
  • 3
    Even though the answer is "no" I don;t see that this is worthy of so many downvotes. It's not a stupid question if you are used to other languages and not easily answered unless you want to read 1000+ pages of specs. It might have been better as "I tried this and it didn't work, so how can I achieve this" instead, but even so... – jcoder Aug 07 '12 at 10:55
  • 1
    Oddly enough `cout << (s + s)` *does* work, so why not `cout << (s * 2)`? No particular reason, it just isn't defined by the language. – Bo Persson Aug 07 '12 at 11:02

10 Answers10

79

std::string has a constructor of the form

std::string(size_type count, char c);

that will repeat the character. For example

#include <iostream>

int main() {
   std::string stuff(2, '.');
   std::cout << stuff << std::endl;
   return 0;
}

will output

..
JRG
  • 2,065
  • 2
  • 14
  • 29
22

I used operator overloading to simulate this behavior in c++.

#include <iostream>
#include <string>
using namespace std;

/* Overloading * operator */
string operator * (string a, unsigned int b) {
    string output = "";
    while (b--) {
        output += a;
    }
    return output;
}


int main() {
    string str = "abc";
    cout << (str * 2);
    return 0;
}

Output: abcabc

pmtatar
  • 353
  • 2
  • 7
17

No, std::string has no operator *. You can add (char, string) to other string. Look at this http://en.cppreference.com/w/cpp/string/basic_string

And if you want this behaviour (no advice this) you can use something like this

#include <iostream>
#include <string>

template<typename Char, typename Traits, typename Allocator>
std::basic_string<Char, Traits, Allocator> operator *
(const std::basic_string<Char, Traits, Allocator> s, size_t n)
{
   std::basic_string<Char, Traits, Allocator> tmp = s;
   for (size_t i = 0; i < n; ++i)
   {
      tmp += s;
   }
   return tmp;
}

template<typename Char, typename Traits, typename Allocator>
std::basic_string<Char, Traits, Allocator> operator *
(size_t n, const std::basic_string<Char, Traits, Allocator>& s)
{
   return s * n;
}

int main()
{
   std::string s = "a";
   std::cout << s * 5 << std::endl;
   std::cout << 5 * s << std::endl;
   std::wstring ws = L"a";
   std::wcout << ws * 5 << std::endl;
   std::wcout << 5 * ws << std::endl;
}

http://liveworkspace.org/code/52f7877b88cd0fba4622fab885907313

ForEveR
  • 55,233
  • 2
  • 119
  • 133
  • 1
    Shouldn't `size_t` rather be `typename std::basic_string::size_type` here? – moooeeeep Jan 05 '16 at 09:32
  • @moooeeeep should be, but it's not very important here. – ForEveR Jan 05 '16 at 09:45
  • 1
    To avoid doing (or potentially doing) multiple reallocations, can use a simple `tmp.reserve(n*s.size())` or similar. I wouldn't advise writing an `operator*()` like this though - a helper function that accepts a string and a repeat count, and returns the result, would arguably be clearer. – Peter Jun 21 '20 at 13:51
5

There is no predefined * operator that will multiply a string by an int, but you can define your own:

#include <iostream>
#include <sstream>
#include <string>

using namespace std;

string operator*(const string& s, unsigned int n) {
    stringstream out;
    while (n--)
        out << s;
    return out.str();
}

string operator*(unsigned int n, const string& s) { return s * n; }

int main(int, char **) {
    string s = ".";
    cout << s * 3 << endl;
    cout << 3 * s << endl;
}
Ferruccio
  • 98,941
  • 38
  • 226
  • 299
2

Strings cannot be multiplied.

If s is a char

'.'     // This has ASCII code 46

then

cout << (char)((int)s * 2);

will give you

'/'     // This has ASCII code 92
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
huseyin tugrul buyukisik
  • 11,469
  • 4
  • 45
  • 97
2

They can't be multipled but I think you can write your own function to do this, something like -

#include <iostream>
#include <string>

std::string operator*(std::string s, size_t count)
{
    std::string ret;
    for(size_t i = 0; i < count; ++i)
    {
        ret = ret + s;
    }
    return ret;
}


int main()
{
    std::string data = "+";
    std::cout << data * 10 << "\n";
}

It's probably not the best idea though, it will be very confusing to anyone looking at the code and not expecting this,

jcoder
  • 29,554
  • 19
  • 87
  • 130
1

Like JRG did, but in a single line

std::cout << std::string(70,'-') << std::endl;

This will create a string, filled with - (dashes), 70 characters long, and breaking the line at the end with std::endl;

0

You can do this:

#include <iostream>
using namespace std;

int main()
{
    string text, new_text;
    int multiply_number;

    cin >> text >> multiply_number;

    /*
        First time in the 'for' loop:  new_text = new_text + text
                                       new_text = "" + "your text"
                                       new_text = "your text"

        Second time in the 'for' loop: new_text = new_text + text
                                       new_text = "your text" + "your text"
                                       new_text = "your textyour text"...n times
    */

    for(int i=0; i<multiply_number; i++)
    {
        new_text += text;
    }

    cout << new_text << endl;    // endl="\n"

    system("pause");
    return 0;
}

In Python you can multiply string like this:

text = "(Your text)"
print(text*200)
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
  • 1
    You can, but even as [the accepted answer](https://stackoverflow.com/a/11843258/3789665) implements *string\*int* pretty much like this: **DON'T**. For starters, use a *double and (conditionally) add* approach. – greybeard Feb 17 '19 at 12:32
  • Re "`system("pause");`": That is operating system dependent. What is the intent? On Windows, it will likely be an infinite delay (until a key is pressed). On Linux it will likely be [a slight delay](https://www.youtube.com/watch?v=r6gN1uO8w6Y&list=PLSoD2CcPrumFJREVL6RmMnZP5U7sGYYi2&index=12&t=5m34s) before it gives up (*"pause: command not found"*). Is the intent to avoid a terminal window closing before the result can be seen? – Peter Mortensen Jun 16 '20 at 16:58
0
std::string StrMultiply(const char* str, size_t count) {
        size_t stringsize = strlen(str);
        size_t buffersize = stringsize * count + 1;
        string res(buffersize,'\0');
        char* end = res._Unchecked_end();
        char* offset = res._Unchecked_begin();
        for (size_t i = 0;i < count; offset += stringsize,i++)
        {
            memcpy(offset, str, stringsize);
        }
        // mark the end
        res[buffersize - 1] = '\0';
        return res;
    }
        inline std::string operator*(std::string left, size_t right) {
            return StrMultiply(left.c_str(), right);
        }

here is a ram-friendly solution, 10 times faster than using stringstreams or string::append

Vafa Sadri
  • 21
  • 2
0

It's surprising that nobody talked about this yet. For assigning char*int to a variable, you can do str.assign(n, char). https://en.cppreference.com/w/cpp/string/basic_string/assign

For example, str.assign(2, 's') would yield ss for the value of str. Other methods to actually achieve the objective have already been mentioned.

Aaron Liu
  • 361
  • 2
  • 13