Can I "multiply" a string (in C#)?
Solution 1
In .NET 4 you can do this:
String.Concat(Enumerable.Repeat("Hello", 4))
Solution 2
Note that if your "string" is only a single character, there is an overload of the string constructor to handle it:
int multipler = 10;
string TenAs = new string ('A', multipler);
Solution 3
Unfortunately / fortunately, the string class is sealed so you can't inherit from it and overload the * operator. You can create an extension method though:
public static string Multiply(this string source, int multiplier)
{
StringBuilder sb = new StringBuilder(multiplier * source.Length);
for (int i = 0; i < multiplier; i++)
{
sb.Append(source);
}
return sb.ToString();
}
string s = "</li></ul>".Multiply(10);
Solution 4
I'm with DrJokepu on this one, but if for some reason you did want to cheat using built-in functionality then you could do something like this:
string snip = "</li></ul>";
int multiplier = 2;
string result = string.Join(snip, new string[multiplier + 1]);
Or, if you're using .NET 4:
string result = string.Concat(Enumerable.Repeat(snip, multiplier));
Personally I wouldn't bother though - a custom extension method is much nicer.
Solution 5
Just for the sake of completeness - here is another way of doing this:
public static string Repeat(this string s, int count)
{
var _s = new System.Text.StringBuilder().Insert(0, s, count).ToString();
return _s;
}
I think I pulled that one from Stack Overflow some time ago, so it is not my idea.
Chromo
Updated on August 25, 2020Comments
-
Chromo over 3 years
I'm coding a small socket Chat Server for personal use, and have come across and issue. My client is a simple program with two threads, one waiting on a user input, the other on the server; this code works perfectly:
import socket import threading from threading import Thread username = input("Username? >") host = input("host ip?") port = 8000 Socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) Socket.connect((host,port)) Socket.send(username.encode()) print(Socket.recv(1024).decode()) def SendMessage(): while True: Socket.send(input("").encode()) def RecvMessage(): while True: print(Socket.recv(1024).decode()) msgthread = Thread(target = SendMessage, args = ()) recvthread = Thread(target = RecvMessage, args = ()) msgthread.start() recvthread.start()
(Forgive the sloppy code, it was thrown together in ~20mins on a Monday evening) As you can see, I am calling two threads, both of which have halting functions in them, and it works seamlessly.
The server, however, is where I am having problems:
import socket import threading from threading import Thread connections = [] host = "" port = 8000 threads = [] def ListenForCommands(): while True: print(input()) def SearchForConnections(): global connections, threads while True: conn, addr = Socket.accept() username = conn.recv(10).decode() conn.send(("You have successfully connected to the server!").encode()) print(username + " (" + str(addr[0]) + ":" + str(addr[1]) + ") Joined") for i in range(len(connections)): if connections[i][0] != conn: connections[i][0].send((username + " Joined").encode()) connections += [[conn,addr,username]] threads += [Thread(target = Listen, args = (conn, ))] threads[-1].start() def Listen(conn): global connections, threads while True: for i in range(len(connections)): if connections[i][0] == conn: username = connections[i][2] try: data = conn.recv(1024).decode() print(username + ": " + data) for i in range(len(connections)): if connections[i][0] != conn: connections[i][0].send((username + ": " + data).encode()) except: print(username + " Disconnected") for i in range(len(connections)): if connections[i][0] == conn: connections.remove(connections[i]) break for i in range(len(connections)): connections[i][0].send((username + " Disconnected").encode()) return; Socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) print("Server created") Socket.bind((host,port)) Socket.listen(3) ListenThread = Thread(target = ListenForCommands, args = ()) ListenThread.start() SearchForConnections()
The source of the problem is in these functions:
def ListenForCommands(): while True: print(input()) def SearchForConnections(): global connections, threads while True: conn, addr = Socket.accept() username = conn.recv(10).decode() conn.send(("You have successfully connected to the server!").encode()) print(username + " (" + str(addr[0]) + ":" + str(addr[1]) + ") Joined") for i in range(len(connections)): if connections[i][0] != conn: connections[i][0].send((username + " Joined").encode()) connections += [[conn,addr,username]] threads += [Thread(target = Listen, args = (conn, ))] threads[-1].start()
The program seems to be halting when arriving at this line
print(username + " (" + str(addr[0]) + ":" + str(addr[1]) + ") Joined")
and works fine without it; however, on the Client Program, this does not seem to be the case.
the ListenForCommands function (as of now just printing out the user input) is being declared as a thread:
ListenThread = Thread(target = ListenForCommands, args = ()) ListenThread.start()
and the SearchForConnections function is being called normally. However, the entire program seems to be being halted until an input is taken from the user, unlike the client side which seems to be working perfectly.
I think I am missing something quite obvious, but have been at a loss for a few hours now, and would love it if someone could help me see the error in my ways!
-
Michael Freidgeim almost 8 yearsPossible duplicate of Is there an easy way to return a string repeated X number of times?
-
-
Marc Gravell over 15 yearsJust where I was going! You could probably optimize by using source.Length * multiplier in the StringBuilder ctor
-
Marc Gravell over 15 yearsYou need (source.Length * multiplier), not just (multiplier)
-
Tamas Czinege over 15 yearsMarc: Are you sure that it means characters and not items?
-
Tamas Czinege over 15 yearsSorry, apparently it is characters.
-
ShigaSuresh over 15 yearsNice, thanks guys, I was hoping for something like the pythonesque (@Vasil) but this will do it more nicely that what I was about to do :D
-
Jronny almost 14 yearsI never knew there was a cheat like this. =)
-
Will Dean almost 14 yearsDidn't even .NET3 have Enumerable.Repeat?
-
Marc Gravell almost 14 years@Will - .NET 3 was WCF/WPF etc, so no; it does exist in .NET 3.5, but then you'd need to
string.Join
it as well - why not just loop n times? Much more direct. -
Will Dean almost 14 yearsThanks - I wasn't thinking properly about 3.0 vs 3.5. As to why not just use a loop, surely that's the whole essence of the functional vs imperative debate? I posted a .net 4 answer lower down which I think is not too bad in the 'functional cleverness' vs 'looping obviousness' debate.
-
Kobi almost 14 yearsTo get a single string you'd still need
String.Concat
, and on 3.5 you'd also need.ToArray()
. Not the most elegant solution, I'm afraid. -
Gabe almost 14 yearsI hope you don't really use
ParallelEnumerable
in situations like this.string.Join
needs to use the elements in order, so parallelizing their generation is uncalled for. -
Jronny almost 14 years@Gabe: Since the items are the same and are really just copies of thisString, there's no need to worry about the ordering here, I guess.
-
sehe about 13 yearsI agree with many teachers in the field that it is usually is good to code to say what you mean. There is no benefit to say you want this parallel and only secretly think "Well, I know it won't be parallel in this particular case anyway"
-
Jronny over 12 yearsI think making it parallel makes it faster, or please enlighten me. That's why I'm converting this to ParallelEnumerable, thus I think I code to say what I mean... Thanks.
-
Mark Foreman over 11 yearsAnd it's not much more in .NET 3.5: String.Concat(Enumerable.Repeat("Hello", 4).ToArray())
-
demented hedgehog almost 9 yearsI don't think it's elegant at all. In python the code to do this is: snip * multiplier (It's not horrible.. but neither is it beautiful).
-
Will Dean almost 9 years@dementedhedgehog I know you acknowledge your own dementia, but even suffering as you do, you might be able to see that a Python example wouldn't have made a very good answer to a C# question... I think most of us can see that language selection is always a compromise, and pretty much any answer to any question could be footnoted with advocacy, either for or against.
-
demented hedgehog almost 9 years@will dean: I was just referring to Matthew Nichols statement about the elegance of the code you have there. As far as I can tell your code is elegant for C#, as it currently stands, for this problem. The point I'm trying to make is: (I believe) it would be very easy (for microsoft, as strings are sealed) to extend C# to overload the * operator to allow int * string multiplication. Which would then actually be elegant in some universal sense, imho, not just elegant within the context of the constraints imposed by C# as it exists at the moment.
-
TEK over 7 years@dementedhedgehog To me, that goes against what binary
operator*
represents. To each their own, I guess. -
demented hedgehog over 7 yearsYeah.. I can appreciate that. Potentially breaks strong typing... could lead to weird errors if you weren't careful. (I still like python grammar+stdlibs much better for string manipulation).
-
Raymond Reddington over 4 yearsThis is really pro.