Converting Char[] to String?

M

Marcio Kleemann

I need to force the first letter of each word in a line of text to
uppercase. The text comes from a TextBox control in a Web Form. I'm new to
..NET and am having a problem.

Since I can't modify the string directly, I convert the string to a char[]
using .ToCharArray() and set the first letter of each word to uppercase. The
problem then is I can't figure out how to convert the char array back to a
string. Whether I use .ToString() from the char[] variable, or
Convert.ToString(), or CharConverter.ConvertToStriong(), I get the same
result - they return a string for the type, i.e."System.Char[]".

How can I convert the contents of the char array back to a string type? Or,
is there a better way for me to force capitalization of the first letter of
each word in a string?

Thanks
 
D

David Browne

Marcio Kleemann said:
I need to force the first letter of each word in a line of text to
uppercase. The text comes from a TextBox control in a Web Form. I'm new to
.NET and am having a problem.

Since I can't modify the string directly, I convert the string to a char[]
using .ToCharArray() and set the first letter of each word to uppercase. The
problem then is I can't figure out how to convert the char array back to a
string. Whether I use .ToString() from the char[] variable, or
Convert.ToString(), or CharConverter.ConvertToStriong(), I get the same
result - they return a string for the type, i.e."System.Char[]".

How can I convert the contents of the char array back to a string type? Or,
is there a better way for me to force capitalization of the first letter of
each word in a string?

char[] chars . . .
string s = new string(chars);

And there's no better, or at least no faster way than string>char[]>string.

David
 
P

Patrick Altman

Marcio,
Here is an example of what I think you might be trying to do:

<snip>
using System;

class StringTest
{
public static void Main()
{
String s = "this is a Test";

Console.WriteLine( CapFirstWord( s ) );
}

public static String CapFirstWord( String Line )
{
String ReturnString = String.Empty;

for( int i=0; i<Line.Length; i++ )
{
if ( i == 0 )
ReturnString = Char.ToUpper( Line ).ToString();
else
ReturnString += Char.ToLower( Line ).ToString();
}

return ReturnString;
}
}
</snip>

Patrick Altman
 
J

Jon Skeet [C# MVP]

How can I convert the contents of the char array back to a string type?
Or, is there a better way for me to force capitalization of the first letter
of each word in a string?

char[] chars . . .
string s = new string(chars);

And there's no better, or at least no faster way than string>char[]>string.

Nope - using StringBuilder is faster unless the strings are
particularly short, because it means only one extra copy is needed. If
the strings are all very short, then constructing the StringBuilder
makes it a bit slower than using the array version.

Below is a benchmark. Here are the results on my laptop:

string->char[]->string: 00:00:52.2968750
string->StringBuilder->string: 00:00:44.2968750

using System;
using System.Text;

class Test
{
const int Iterations = 50000;

static readonly string[] TestStrings =
{
"a pretty short string",
new string('x', 10000),
new string('y', 100000)
};

static void Main()
{
{
DateTime start = DateTime.Now;
for (int i=0; i < Iterations; i++)
{
foreach (string x in TestStrings)
{
UpperCase1(x);
}
}
DateTime end = DateTime.Now;
Console.WriteLine ("string->char[]->string: {0}",
end-start);
}


{
DateTime start = DateTime.Now;
for (int i=0; i < Iterations; i++)
{
foreach (string x in TestStrings)
{
UpperCase2(x);
}
}
DateTime end = DateTime.Now;
Console.WriteLine ("string->StringBuilder->string: {0}",
end-start);
}
}

static string UpperCase1 (string original)
{
char[] chars = original.ToCharArray();
chars[0]=Char.ToUpper(chars[0]);
return new string(chars);
}

static string UpperCase2 (string original)
{
StringBuilder builder = new StringBuilder(original);
builder[0] = Char.ToUpper(original[0]);
return builder.ToString();
}
}
 
J

Jon Skeet [C# MVP]

Marcio,
Here is an example of what I think you might be trying to do:

<snip>
using System;

class StringTest
{
public static void Main()
{
String s = "this is a Test";

Console.WriteLine( CapFirstWord( s ) );
}

public static String CapFirstWord( String Line )
{
String ReturnString = String.Empty;

for( int i=0; i<Line.Length; i++ )
{
if ( i == 0 )
ReturnString = Char.ToUpper( Line ).ToString();
else
ReturnString += Char.ToLower( Line ).ToString();
}

return ReturnString;
}
}


That's a terrible way to do it, unfortunately - using string
concatenation will make this incredibly slow and give a lot of memory
churn when the size of the string increases. Fortunately, it's
unnecessary - see other posts - but in general when building a string
in this kind of way, StringBuilder is the way to go.
 
P

Patrick Altman

Jon,

You are correct. After borrowing some of code in a previous message on this
thread, it's easy to see that StringBuilder is a little more than twice as
fast as concatenation. Thanks for that catch -- learned something new
today!

Patrick Altman



Jon Skeet said:
Marcio,
Here is an example of what I think you might be trying to do:

<snip>
using System;

class StringTest
{
public static void Main()
{
String s = "this is a Test";

Console.WriteLine( CapFirstWord( s ) );
}

public static String CapFirstWord( String Line )
{
String ReturnString = String.Empty;

for( int i=0; i<Line.Length; i++ )
{
if ( i == 0 )
ReturnString = Char.ToUpper( Line ).ToString();
else
ReturnString += Char.ToLower( Line ).ToString();
}

return ReturnString;
}
}


That's a terrible way to do it, unfortunately - using string
concatenation will make this incredibly slow and give a lot of memory
churn when the size of the string increases. Fortunately, it's
unnecessary - see other posts - but in general when building a string
in this kind of way, StringBuilder is the way to go.
 
P

Paul E Collins

Marcio Kleemann said:
How can I convert the contents of the char array
back to a string type?

char[] c = new char[] { 'a', 'b', 'c' };
string s = new string(c);
Or, is there a better way for me to force
capitalization of the first letter of each word
in a string?

Well, I don't see why you can't just iterate over the string and
either make a copy or modify a StringBuilder. I don't think I'd bother
converting it to a char array, personally.

P.
 
J

Jon Skeet [C# MVP]

You are correct. After borrowing some of code in a previous message on this
thread, it's easy to see that StringBuilder is a little more than twice as
fast as concatenation. Thanks for that catch -- learned something new
today!

The "little more than twice" depends on the length of the original
string. For very short strings, your way may actually be faster. For
very long strings, however, it could be much, *much* slower - millions
of times slower! (Basically the StringBuilder solution is O(n) whereas
using concatenation is O(n^2).)
 
P

Paul E Collins

David Browne said:
is there a better way for me to force capitalization
of the first letter of each word in a string?

[...] there's no better, or at least no faster way than
string>char[]>string.

I'm thinking that String.Split might be handy to break up the words
efficiently; then you'd only have to capitalise each resulting word
instead of scanning through all the characters. It may not be any
faster (depending on underlying implementation), but it's perhaps
simpler.

P.
 
P

Patrick Altman

So, in applying this knowledge of StringBuilder versus Concatenation, what
should be the general rule of thumb of when to use either one? Is there a
some threshold of string length that it is more efficient to use one over
the other? What lengths qualify for "very long strings"?

Thanks,
Patrick Altman
 
R

Rachel Suddeth

Rule of thumb... if you would build anything more then 3 characters one
character at a time... you should use StringBuilder. If you don't know how
long they'll be... use StringBuilder.

In case you don't know ... any time you make any change to a string, a whole
new string gets created (new memory allocation.) So the rule is not really
on the length of the string, but on how many operations you will do to it.

-Rachel

Patrick Altman said:
So, in applying this knowledge of StringBuilder versus Concatenation, what
should be the general rule of thumb of when to use either one? Is there a
some threshold of string length that it is more efficient to use one over
the other? What lengths qualify for "very long strings"?

Thanks,
Patrick Altman


on
twice
 
J

Jon Skeet [C# MVP]

So, in applying this knowledge of StringBuilder versus Concatenation, what
should be the general rule of thumb of when to use either one? Is there a
some threshold of string length that it is more efficient to use one over
the other? What lengths qualify for "very long strings"?

Any time you build a string within a loop, I'd suggest using
StringBuilder. If you're building it in code, eg

string x = "hello ";
x += "there ";
x += "my ";
x += "name ";
x += "is ";
x += "Jon.";

then you might apply some kind of "more than 5 or 10 concatenations =>
use a StringBuilder" rule of thumb, but it's unlikely to make a huge
difference. Using it in a loop (especially when you don't know the
number of iterations ahead of time) is the potential performance
killer.
 
D

David Browne

Jon Skeet said:
How can I convert the contents of the char array back to a string type?
Or, is there a better way for me to force capitalization of the first letter
of each word in a string?

char[] chars . . .
string s = new string(chars);

And there's no better, or at least no faster way than
string>char[]>string.

Nope - using StringBuilder is faster unless the strings are
particularly short, because it means only one extra copy is needed.

Ahh, I forgot that StringBuilder.ToString() cheats, not returning a copy
like we mere mortals would have to.

David
 
D

David

How can I convert the contents of the char array back to a string type?
Or, is there a better way for me to force capitalization of the first letter
of each word in a string?

char[] chars . . .
string s = new string(chars);

And there's no better, or at least no faster way than string>char[]>string.

Nope - using StringBuilder is faster unless the strings are
particularly short, because it means only one extra copy is needed. If
the strings are all very short, then constructing the StringBuilder
makes it a bit slower than using the array version.


Of course, the assumption that the strings are very short is a pretty
reasonable assumption in the original post, since we're dealing with a
single line of text of (presumably) english words.
 
D

David

How can I convert the contents of the char array back to a string type? Or,
is there a better way for me to force capitalization of the first letter of
each word in a string?

Personally, I'd probably go for a regular expression here, just because
I find it much shorter and much easier to read, assuming you're used to
regexes...

public string UpperCaseWords(string input)
{
return Regex.Replace(s, @"\b\w", new MatchEvaluator(UpperCaseMatches));
}

private string UpperCaseMatches(Match match)
{
return match.value.ToUpper();
}
 
J

Jon Skeet [C# MVP]

David said:
And there's no better, or at least no faster way than string>char[]>string.

Nope - using StringBuilder is faster unless the strings are
particularly short, because it means only one extra copy is needed. If
the strings are all very short, then constructing the StringBuilder
makes it a bit slower than using the array version.

Of course, the assumption that the strings are very short is a pretty
reasonable assumption in the original post, since we're dealing with a
single line of text of (presumably) english words.

By "particularly short" here, I mean really, really short - just a very
few characters. Even with just 50 characters you end up shuffling about
2.5K around instead of 100 bytes, if you use repeated concatenation.
 
D

David

By "particularly short" here, I mean really, really short - just a very
few characters. Even with just 50 characters you end up shuffling about
2.5K around instead of 100 bytes, if you use repeated concatenation.

In some simple benchmarking (obviously not guaranteed accurate), the two
techniques seem to even out at about 20-25 characters, which seems to me
to be the upper end of natural length for the things you'd probably want
to capitalize: titles and proper names (names and popular titles are
generally shorter, but academic titles are often much longer).

Although I might have subthreads confused here, but I thought the
repeated concatenation code was in another subthread. This particular
line of posts was merely comparing the string.ToCharArray() and new
string(char[]) vs. new StringBuilder(string) and builder.ToString().
Neither of those is going to be pushing 2.5K around for a 50 byte
string, AFAIK.
 
J

Jon Skeet [C# MVP]

David said:
In some simple benchmarking (obviously not guaranteed accurate), the two
techniques seem to even out at about 20-25 characters, which seems to me
to be the upper end of natural length for the things you'd probably want
to capitalize: titles and proper names (names and popular titles are
generally shorter, but academic titles are often much longer).

Hmm... I saw things evening out between 10 and 15 characters. By 20
characters StringBuilder has the upper hand. It's pretty much of a
muchness in that range though, yes.
Although I might have subthreads confused here, but I thought the
repeated concatenation code was in another subthread. This particular
line of posts was merely comparing the string.ToCharArray() and new
string(char[]) vs. new StringBuilder(string) and builder.ToString().
Neither of those is going to be pushing 2.5K around for a 50 byte
string, AFAIK.

You're absolutely right on this bit - that's what comes of me posting
before I'm properly awake.
 
M

Marcio Kleemann

Thanks to everyone for the detailed replies and comparisons between the
various possibilities!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Top