614

I have a DetailsView with a TextBox and I want the input data be saved always with the first letter in capital.

Example:

"red" --> "Red"
"red house" --> " Red house"

How can I achieve this maximizing performance?


Note:

Based on the answers and the comments under the answers, many people think this is asking about capitalizing all words in the string. E.g. => Red House It isn't, but if that is what you seek, look for one of the answers that uses TextInfo's ToTitleCase method. (Note: Those answers are incorrect for the question actually asked.) See TextInfo.ToTitleCase documentation for caveats (doesn't touch all-caps words - they are considered acronyms; may lowercase letters in middle of words that "shouldn't" be lowered, e.g., "McDonald" → "Mcdonald"; not guaranteed to handle all culture-specific subtleties re capitalization rules.)


Note:

The question is ambiguous as to whether letters after the first should be forced to lower case. The accepted answer assumes that only the first letter should be altered. If you want to force all letters in the string except the first to be lower case, look for an answer containing ToLower, and not containing ToTitleCase.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
  • 10
    @Bobby: It's not a duplicate: the OP asks to capitalize the first letter of a string, the question in the link capitalizes the first letter of each word. – GvS Nov 09 '10 at 16:31
  • 2
    @GvS: The first answer is *very* detailed and the first code-block is *exactly* what he is looking for. Also, between capitalising every word and only the first word is just one loop difference. – Bobby Nov 09 '10 at 17:23
  • 2
    But you said, and I quote, "Make first letter of EACH WORD upper case". Therefore, why "red house" --> " Red house"? Why the "h" of "house" is not a capital letter? – Guillermo Gutiérrez Oct 30 '12 at 20:02
  • don't forget assuming you're using a computer, you can do this: http://stackoverflow.com/a/1206029/294884 – Fattie Feb 11 '16 at 00:18
  • @Fattie - Useful link, However this question is *not* about *capitalizing each word* - it is about changing *only the first letter of the string* to a capital. – ToolmakerSteve Apr 10 '17 at 18:22

44 Answers44

808

Solution in different C# versions

C# 8 with at least .NET Core 3.0 or .NET Standard 2.1

public static class StringExtensions
{
    public static string FirstCharToUpper(this string input) =>
        input switch
        {
            null => throw new ArgumentNullException(nameof(input)),
            "" => throw new ArgumentException($"{nameof(input)} cannot be empty", nameof(input)),
            _ => string.Concat(input[0].ToString().ToUpper(), input.AsSpan(1))
        };
}

Since .NET Core 3.0 / .NET Standard 2.1 String.Concat() supports ReadonlySpan<char> which saves one allocation if we use .AsSpan(1) instead of .Substring(1).

C# 8

public static class StringExtensions
{
    public static string FirstCharToUpper(this string input) =>
        input switch
        {
            null => throw new ArgumentNullException(nameof(input)),
            "" => throw new ArgumentException($"{nameof(input)} cannot be empty", nameof(input)),
            _ => input[0].ToString().ToUpper() + input.Substring(1)
        };
}

C# 7

public static class StringExtensions
{
    public static string FirstCharToUpper(this string input)
    {
        switch (input)
        {
            case null: throw new ArgumentNullException(nameof(input));
            case "": throw new ArgumentException($"{nameof(input)} cannot be empty", nameof(input));
            default: return input[0].ToString().ToUpper() + input.Substring(1);
        }
    }
}

Really old answers

public static string FirstCharToUpper(string input)
{
    if (String.IsNullOrEmpty(input))
        throw new ArgumentException("ARGH!");
    return input.First().ToString().ToUpper() + String.Join("", input.Skip(1));
}

This version is shorter. For a faster solution, take a look at Diego's answer.

public static string FirstCharToUpper(string input)
{
    if (String.IsNullOrEmpty(input))
        throw new ArgumentException("ARGH!");
    return input.First().ToString().ToUpper() + input.Substring(1);
}

Probably the fastest solution is Darren's (There's even a benchmark) although I would change it's string.IsNullOrEmpty(s) validation to throw an exception since the original requirement expects for a first letter to exist so it can be uppercased. Note that this code works for a generic string and not particularly on valid values from the Textbox.

Carlos Muñoz
  • 17,397
  • 7
  • 55
  • 80
  • Why not `return String.Join(input.First().ToString().ToUpper(), input.Skip(1));` if you're going to use String.Join in the first place – Nilzor Jan 24 '12 at 11:23
  • 2
    Because first parameter of `String.Join` is separator with which to join strings given with second parameter. – Dialecticus Feb 10 '12 at 16:11
  • 36
    I really like your answer, but `var arr = input.ToCharArray(); arr[0] = Char.ToUpperInvariant(arr[0]); return new String(arr);` would probably gain some speed since you are creating less immutable objects (and especially you are skipping the `String.Join`). This of course depends on the length of the string. – flindeberg Aug 26 '13 at 14:22
  • `return input.First().ToString().ToUpper() + String.Join("", input.ToLower().Skip(1));` – Gaui Apr 23 '14 at 18:41
  • 1
    @Gaui, In no place it says remaining letters should be lowercase – Carlos Muñoz Apr 23 '14 at 18:49
  • 12
    Hmmm... Technically, this should return `"Argh!"` to keep with the **Upper Case First Letter** rule. ;) –  Apr 24 '15 at 19:52
  • 2
    @jp2code Since capitalizing a nonexistent first letter in a null or empty string is like getting slapped by a pregnant dolphing, then the ALL CAPS ARGH! is the correct spelling. http://www.urbandictionary.com/define.php?term=ARGH&defid=67839 – Carlos Muñoz May 04 '15 at 17:03
  • `CultureInfo.CurrentCulture.TextInfo.ToTitleCase("MY STRING");` – Rodrigo Reis Jan 21 '16 at 15:28
  • @RodrigoReis take a look at [Equiso's old answer](http://stackoverflow.com/a/4135491/186133) to see why this is not correct – Carlos Muñoz Jan 21 '16 at 15:42
  • @RodrigoReis - and FYI, ironically, you failed to notice that ToTitleCase says in its documentation that it *does not alter all-caps words*, because they might be acronyms. So, `ToTitleCase("MY STRING")` would return `"MY STRING"`! ;) – ToolmakerSteve Apr 10 '17 at 20:46
  • @CarlosMuñoz - did you *read* the explanation as to *why* the answer Darren quotes is faster? Has nothing to do with what you test before the main statement - that is the same in both tests. It is because one approach creates two strings, the other one. I won't argue with your edit, since this is your answer, but your edit of my edit "muddies the water". The other approach is *without a doubt* faster. The discussion of what to test at the start of the method is a separate topic - on that, you raise an excellent point. :) – ToolmakerSteve Apr 11 '17 at 03:43
  • @ToolmakerSteve Yes man, I've see this on Jan 21 '16 at 15:43 – Rodrigo Reis Apr 27 '17 at 19:00
  • C# does not contain a string function First(). How can this be the accepted answer? I reviewed the MSDN to see if I was wrong on this, but no, it's not in there, there is no list indexer. https://stackoverflow.com/questions/3878820/c-how-to-get-first-char-of-a-string – Peter Suwara Mar 11 '18 at 14:30
  • It is true that `String` does not have a `.First()` mthod but `String` implements `IEnumerable` which means you can use LINQ extensions methods including `.First()` on instances of `String`. BTW String documentation DOES include references to extension methods in string: https://learn.microsoft.com/es-es/dotnet/api/system.string?view=netcore-2.0#Extension_Methods – Carlos Muñoz Mar 12 '18 at 14:18
  • 1
    Is there a reason to use `.First()` over `[0]`? – Pavel Jul 11 '18 at 05:45
  • @Pavel Actually [0] is faster than First() so I would use index based retrieval than using LINQ – Ruchira Sep 21 '18 at 00:47
  • Syntax of the C# 8 is wrong, you have 1 additional bracket as you are doing an expression body and not a block body. – Theodor Solbjørg Apr 17 '20 at 14:43
  • Not sure what definition of "fast" you go by but damn this isn't fast – John May 09 '20 at 21:11
  • @John You do realize this is a generic solution without more context? Without context there is no such thing as fast or slow. – Carlos Muñoz May 09 '20 at 21:19
  • They said (with maximum performance). So give them it. As I did on my edit – John May 09 '20 at 21:21
  • I'd avoid throwing exception in case when input string is "" because it should be considered as fully valid case (unlike null).The empty string should be returned instead. – zhe Aug 13 '20 at 15:33
  • @zhe You are free to implement it as you want but actually it's not a valid case. That exceptions are preconditions on the input string. An empty string has no first letter thus it is impossible to return a value that complies with the requirement. It is like dividing by zero. – Carlos Muñoz Aug 13 '20 at 15:38
  • @CarlosMuñoz no, you're wrong. For instance check the standard CLR String.ToUpper() method. It does not throw exception on empty string and considers it a valid case and returns empty string. https://learn.microsoft.com/en-us/dotnet/api/system.string.toupper?view=netcore-3.1 – zhe Aug 15 '20 at 15:15
  • The fact that that behavior is in the BCL doesn't make it right. It is that way because it's more usefull. In a language where null exists, some libraries try to protect you from it. Such as Windows Forms where an empty Textbox returns an empty string not null. Given that there is very likely that you will need to handle empty strings as well as null and is also very likely that you will try to call `ToUpper()` on `TextBox.Text` it is possible that they decided to impñement it that way in order to prevent exceptions being thrown in such circumstances, so you don't need to do the check – Carlos Muñoz Aug 16 '20 at 07:19
  • This answer is actually wrong. It doesn't capitalize the first character when the string starts with white space. If we edit the string before it gets here, we will still have to deal with adding the whitespace if we want it. Read the expected answer, please. – Patrick Knott Aug 04 '21 at 20:51
  • @PatrickKnott You are wrong. It does capitalize the first character in the string which happens to be the space. – Carlos Muñoz Aug 04 '21 at 21:31
  • yes, but you will notice in the poorly worded question: "red house" --> " Red house" I take that to mean that space means that a " red" should become " Red". And... I might add, a space is not a letter. Hence, this answer with 703 votes minus my 1 is actually wrong. I admit, it is troll-ish to say that, but an anon question giver with a poorly worded question has provided a poorly worded solution; your solution provides a suitable answer which has helped many people. However, it does not capitalize the first letter if the char isn't a letter, which is my point and the question. – Patrick Knott Aug 04 '21 at 22:06
  • @PatrickKnott you are assuming things, as everyone else. An answer is not wrong if it states what is assuming when the OP is not around anymore. – Carlos Muñoz Aug 05 '21 at 01:23
  • "Make first Letter uppercase" is not my assuming, especially when the answer shows: "red house" --> " Red house". The missing space is an obvious typo, but even without it, the first letter may be index 2. The denoted character to capitalize is a letter. Your solution does not account for ex. "1abc" to make the A capitalized. This is the same as any trick question on a college test, trollish though it might be. The fact you have so many upvotes is indicative of the helpful, educational code you provide. But the answer is still academically incorrect if the question is taken literally. – Patrick Knott Aug 05 '21 at 17:01
  • ToTitleCase is sometimes more accurate from a i18n perspective https://learn.microsoft.com/en-us/dotnet/api/system.globalization.textinfo.totitlecase?view=net-5.0 – Jonas Stensved Nov 03 '21 at 17:58
  • @JonasStensved You are correct, but that's not the requirement for this question. `TotTitleCase` converts the first char from every word to uppercase not only the first char in the string. – Carlos Muñoz Nov 04 '21 at 11:50
  • I would have thought Regex was the best way of handling this – Mark Homer Feb 21 '22 at 13:16
395
public string FirstLetterToUpper(string str)
{
    if (str == null)
        return null;

    if (str.Length > 1)
        return char.ToUpper(str[0]) + str.Substring(1);

    return str.ToUpper();
}

this can also be written as

public string ToTitleCase(string str)
{
    var firstword = System.Globalization.CultureInfo.CurrentCulture.TextInfo.ToTitleCase(str.Split(' ')[0].ToLower());
    str = str.Replace(str.Split(' ')[0],firstword);
    return str;
}

Where it picks up the first word and converts it to title case then replaces it in the input string.

Vinod Srivastav
  • 3,644
  • 1
  • 27
  • 40
Diego
  • 19,494
  • 4
  • 32
  • 46
  • But this converts every first letter of a word to uppercase, not only the first character of a string. – GvS Nov 09 '10 at 15:42
  • @GvS, that's what the question asks you to do. – thattolleyguy Nov 09 '10 at 15:45
  • 26
    He asks "red house" => "Red house". ToTitleCase will give you "Red House". – GvS Nov 09 '10 at 15:47
  • @Equiso: That edit really did not help. The ToTitleString still converts the first letter of each word to an uppercase. – GvS Nov 09 '10 at 16:30
  • 1
    @GvS, yes that is why I say that that was my old answer and make every first letter to uppercase – Diego Nov 09 '10 at 16:34
  • @Equiso: Sorry mate, missed the last update. This looks correct to me. – GvS Nov 09 '10 at 16:38
  • 1
    Not sure about this but char + string causes a boxing. Just in case max performance is the requirement. – nawfal Sep 13 '17 at 04:39
  • return char.ToUpper(str[0]) + str.Substring(1); You've got to add to lower on the second part, if not then it won't work when receiving all caps on the input. – ArnaldoRivera Dec 22 '21 at 21:10
  • @ArnaldoRivera If you see the Question it is about to make first letter of string capital not making `Title` case – Vinod Srivastav Feb 22 '23 at 13:05
221

The right way is to use Culture:

System.Globalization.CultureInfo.CurrentCulture.TextInfo.ToTitleCase(word.ToLower())

Note: This will capitalise each word within a string, e.g. "red house" --> "Red House". The solution will also lower-case capitalisation within words, e.g. "old McDonald" --> "Old Mcdonald".

AZ_
  • 21,688
  • 25
  • 143
  • 191
GPY
  • 3,832
  • 1
  • 16
  • 11
  • 28
    Six years after the question was asked, please do a more thorough job of *reading existing answers and their comments*. If you are convinced you have a better solution, then *show* the situations in which your answer behaves in a way you think is superior, and specifically how that differs from existing answers. 1) Equiso already covered this option, in second half of his answer. 2) For many situations, `ToLower` is a mistake, as it wipes out capitalization in middle of word, e.g. "McDonalds". 3) The question is about *changing just the first word of the string*, **not** about TitleCase. – ToolmakerSteve Apr 10 '17 at 19:12
  • 2
    Good Culture does not hurt anyway. Other viewers might not have the "only first letter" requirement. – JB. May 07 '20 at 09:00
  • A equally correct answer could be word.ToUpper() - it changes the first letter to upper case and we don't bother about the rest. – Peter Hedberg Jul 02 '20 at 09:08
  • Is "Culture" literal? – Peter Mortensen Jul 12 '21 at 20:25
91

I took the fastest method from C# Uppercase First Letter - Dot Net Perls and converted to an extension method:

    /// <summary>
    /// Returns the input string with the first character converted to uppercase, or mutates any nulls passed into string.Empty
    /// </summary>
    public static string FirstLetterToUpperCaseOrConvertNullToEmptyString(this string s)
    {
        if (string.IsNullOrEmpty(s))
            return string.Empty;

        char[] a = s.ToCharArray();
        a[0] = char.ToUpper(a[0]);
        return new string(a);
    }

NOTE: The reason using ToCharArray is faster than the alternative char.ToUpper(s[0]) + s.Substring(1), is that only one string is allocated, whereas the Substring approach allocates a string for the substring, and then a second string to compose the final result.


Here is what this approach looks like, combined with the initial test from CarlosMuñoz's accepted answer:

    /// <summary>
    /// Returns the input string with the first character converted to uppercase
    /// </summary>
    public static string FirstLetterToUpperCase(this string s)
    {
        if (string.IsNullOrEmpty(s))
            throw new ArgumentException("There is no first letter");

        char[] a = s.ToCharArray();
        a[0] = char.ToUpper(a[0]);
        return new string(a);
    }
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Darren
  • 9,014
  • 2
  • 39
  • 50
  • Wow, thanks for finding performance metrics, to show a superior-performance solution! – ToolmakerSteve Apr 10 '17 at 20:19
  • @ToolmakerSteve, I like this solution as it indeed seems faster than others but there's a little problem with this. If you pass null you shouldn't get an empty string as output. In fact I would argue that even passing an empty string should throw an exception since the OP asks for the *first* letter. Also, you could comment on other people's answer before editing them. – Carlos Muñoz Apr 10 '17 at 22:12
  • 2
    @CarlosMuñoz - it has been discussed in meta, whether to "improve" other people's answers. The consensus was "if you can improve an answer, then do so - no one 'owns' an answer, not even the original author - the goal is to have the best possible answers". You are of course free to edit or rollback the edit. In which case, common courtesy would let the original author's version be the final result, and I would settle for commenting. Usually I *also* put in a comment the change I am making; I apologize if I did not. – ToolmakerSteve Apr 11 '17 at 03:28
  • @CarlosMuñoz - in particular, there are many, many answers in SO, that are not actively maintained. If a change would improve an answer, why leave it buried in a comment? If the author is actively monitoring their answers, they will do with the change as they see fit. If they are not, then the answer has been improved, to everyone's benefit. This principle is *especially* true, for old Q & A's, such as this one. – ToolmakerSteve Apr 11 '17 at 03:34
  • BTW, I agree with @CarlosMuñoz about the test at the start of the method - his version of that test is better programming style - the `return string.Empty` here would hide a "bad" call to the method. – ToolmakerSteve Apr 11 '17 at 03:51
  • 1
    Darren, I'm going to edit your answer to add alternative code, that shows what your solution looks like, with @CarlosMuñoz initial test. I believe your contribution was finding a higher performance solution, and that you won't mind this addition. If you don't like it, please do as you see fit with my edit. – ToolmakerSteve Apr 11 '17 at 04:10
  • 1
    @ToolmakerSteve Agree it should ideally not mutate a null to an empty string, but it is handy for my use case so I'll just rename the original method. – Darren Apr 12 '17 at 00:45
  • 1
    I benchmarked all the answers and this won. Also changing to `char.ToUpperInvariant` is even 20% faster – Alex from Jitbit Apr 12 '22 at 18:46
53

You can use the "ToTitleCase method":

string s = new CultureInfo("en-US").TextInfo.ToTitleCase("red house");
//result : Red House

This extension method solves every titlecase problem.

It is easy to use:

string str = "red house";
str.ToTitleCase();
//result : Red house

string str = "red house";
str.ToTitleCase(TitleCase.All);
//result : Red House

The extension method:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;

namespace Test
{
    public static class StringHelper
    {
        private static CultureInfo ci = new CultureInfo("en-US");
        //Convert all first latter
        public static string ToTitleCase(this string str)
        {
            str = str.ToLower();
            var strArray = str.Split(' ');
            if (strArray.Length > 1)
            {
                strArray[0] = ci.TextInfo.ToTitleCase(strArray[0]);
                return string.Join(" ", strArray);
            }
            return ci.TextInfo.ToTitleCase(str);
        }

        public static string ToTitleCase(this string str, TitleCase tcase)
        {
            str = str.ToLower();
            switch (tcase)
            {
                case TitleCase.First:
                    var strArray = str.Split(' ');
                    if (strArray.Length > 1)
                    {
                        strArray[0] = ci.TextInfo.ToTitleCase(strArray[0]);
                        return string.Join(" ", strArray);
                    }
                    break;
                case TitleCase.All:
                    return ci.TextInfo.ToTitleCase(str);
                default:
                    break;
            }
            return ci.TextInfo.ToTitleCase(str);
        }
    }

    public enum TitleCase
    {
        First,
        All
    }
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
İbrahim Özbölük
  • 3,162
  • 23
  • 20
  • 2
    The problem with you solution is that "red house" will be converted to "Red House" and not to "Red house" as it was asked in the question. – Vadim Oct 09 '13 at 19:31
  • 5
    @Tacttin It will work but the following code is easier to read and performs better char.ToUpper(text[0]) + ((text.Length > 1) ? text.Substring(1).ToLower() : string.Empty); You can read more @ http://vkreynin.wordpress.com/2013/10/09/capitalize-only-first-character-c/ – Vadim Oct 10 '13 at 18:07
  • 2
    I don't like this solution, because it combines two quite different situations into one lengthy method. I don't see a conceptual benefit either. And the implementation of capitalizing just the first letter is .. ridiculous. If you want to capitalize the first letter, the obvious implementation is *to just capitalize (ToUpper) the first letter*. Instead of this, I would have two separate methods. `FirstLetterToUpper` in Equiso's answer (or in Guillernet's newer answer), and `ToTitleCase` here, but without the second parameter. Then don't need `enum TitleCase`. – ToolmakerSteve Apr 10 '17 at 19:04
39

For the first letter, with error checking:

public string CapitalizeFirstLetter(string s)
{
    if (String.IsNullOrEmpty(s))
        return s;
    if (s.Length == 1)
        return s.ToUpper();
    return s.Remove(1).ToUpper() + s.Substring(1);
}

And here's the same as a handy extension

public static string CapitalizeFirstLetter(this string s)
{
    if (String.IsNullOrEmpty(s))
        return s;
    if (s.Length == 1)
        return s.ToUpper();
    return s.Remove(1).ToUpper() + s.Substring(1);
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Kobi
  • 135,331
  • 41
  • 252
  • 292
15

Using string.Create() and avoiding the throw keyword in our method (yes, you read it right), we can take Marcell's answer one step further. Also, my method handles strings of arbitrary length (e.g., several megabytes of text).

public static string L33t(this string s)
{
    static void ThrowError() => throw new ArgumentException("There is no first letter");

    if (string.IsNullOrEmpty(s))
        ThrowError();                      // No "throw" keyword to avoid costly IL

    return string.Create(s.Length, s, (chars, state) =>
    {
        state.AsSpan().CopyTo(chars);      // No slicing to save some CPU cycles
        chars[0] = char.ToUpper(chars[0]);
    });
}

Performance

Here are the numbers for benchmarks run on .NET Core 3.1.7, 64 bit. I added a longer string to pinpoint the cost of extra copies.

Method Data Mean Error StdDev Median
L33t red 8.545 ns 0.4612 ns 1.3308 ns 8.075 ns
Marcell red 9.153 ns 0.3377 ns 0.9471 ns 8.946 ns
L33t red house 7.715 ns 0.1741 ns 0.4618 ns 7.793 ns
Marcell red house 10.537 ns 0.5002 ns 1.4351 ns 10.377 ns
L33t red r(...)house [89] 11.121 ns 0.6774 ns 1.9106 ns 10.612 ns
Marcell red r(...)house [89] 16.739 ns 0.4468 ns 1.3033 ns 16.853 ns

Full test code

using System;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;

namespace CorePerformanceTest
{
    class Program
    {
        static void Main(string[] args)
        {
            var summary = BenchmarkRunner.Run<StringUpperTest>();
        }
    }

    public class StringUpperTest
    {
        [Params("red", "red house", "red red red red red red red red red red red red red red red red red red red red red house")]
        public string Data;

        [Benchmark]
        public string Marcell() => Data.Marcell();

        [Benchmark]
        public string L33t() => Data.L33t();
    }

    internal static class StringExtensions
    {
        public static string Marcell(this string s)
        {
            if (string.IsNullOrEmpty(s))
                throw new ArgumentException("There is no first letter");

            Span<char> a = stackalloc char[s.Length];
            s.AsSpan(1).CopyTo(a.Slice(1));
            a[0] = char.ToUpper(s[0]);
            return new string(a);
        }

        public static string L33t(this string s)
        {
            static void ThrowError() => throw new ArgumentException("There is no first letter");

            if (string.IsNullOrEmpty(s))
                ThrowError(); // IMPORTANT: Do not "throw" here!

            return string.Create(s.Length, s, (chars, state) =>
            {
                state.AsSpan().CopyTo(chars);
                chars[0] = char.ToUpper(chars[0]);
            });
        }
    }
}

Please let me know if you can make it any faster!

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
l33t
  • 18,692
  • 16
  • 103
  • 180
  • Why can't you use the throw keyword after `string.IsNullOrEmpty` (IMPORTANT: Do not "throw" here!)? – Casper Sep 18 '20 at 14:16
  • 1
    You *can* use the `throw` keyword, but its mere existence will prevent certain compiler optimizations, like inlining. You can run the sample with and without it, and you will see that it really does affect performance. – l33t Sep 21 '20 at 07:10
13
public static string ToInvarianTitleCase(this string self)
{
    if (string.IsNullOrWhiteSpace(self))
    {
        return self;
    }

    return CultureInfo.InvariantCulture.TextInfo.ToTitleCase(self);
}
Noctis
  • 11,507
  • 3
  • 43
  • 82
Taras Alenin
  • 8,094
  • 4
  • 40
  • 32
11

As this question is about maximizing performance, I adopted Darren's version to use Spans, which reduces garbage and improves speed by about 10%.

/// <summary>
/// Returns the input string with the first character converted to uppercase
/// </summary>
public static string ToUpperFirst(this string s)
{
    if (string.IsNullOrEmpty(s))
        throw new ArgumentException("There is no first letter");

    Span<char> a = stackalloc char[s.Length];
    s.AsSpan(1).CopyTo(a.Slice(1));
    a[0] = char.ToUpper(s[0]);
    return new string(a);
}

Performance

Method Data Mean Error StdDev
Carlos red 107.29 ns 2.2401 ns 3.9234 ns
Darren red 30.93 ns 0.9228 ns 0.8632 ns
Marcell red 26.99 ns 0.3902 ns 0.3459 ns
Carlos red house 106.78 ns 1.9713 ns 1.8439 ns
Darren red house 32.49 ns 0.4253 ns 0.3978 ns
Marcell red house 27.37 ns 0.3888 ns 0.3637 ns

Full test code

using System;
using System.Linq;

using BenchmarkDotNet.Attributes;

namespace CorePerformanceTest
{
    public class StringUpperTest
    {
        [Params("red", "red house")]
        public string Data;

        [Benchmark]
        public string Carlos() => Data.Carlos();

        [Benchmark]
        public string Darren() => Data.Darren();

        [Benchmark]
        public string Marcell() => Data.Marcell();
    }

    internal static class StringExtensions
    {
        public static string Carlos(this string input) =>
            input switch
            {
                null => throw new ArgumentNullException(nameof(input)),
                "" => throw new ArgumentException($"{nameof(input)} cannot be empty", nameof(input)),
                _ => input.First().ToString().ToUpper() + input.Substring(1)
            };

        public static string Darren(this string s)
        {
            if (string.IsNullOrEmpty(s))
                throw new ArgumentException("There is no first letter");

            char[] a = s.ToCharArray();
            a[0] = char.ToUpper(a[0]);
            return new string(a);
        }

        public static string Marcell(this string s)
        {
            if (string.IsNullOrEmpty(s))
                throw new ArgumentException("There is no first letter");

            Span<char> a = stackalloc char[s.Length];
            s.AsSpan(1).CopyTo(a.Slice(1));
            a[0] = char.ToUpper(s[0]);
            return new string(a);
        }
    }

}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Marcell Toth
  • 3,433
  • 1
  • 21
  • 36
  • 3
    You should probably safe-guard against super long strings. `stackalloc` will smash the stack if you have more than around ~1MB of characters. – l33t Sep 14 '20 at 08:40
  • Please see my [improved answer](https://stackoverflow.com/a/63886117/419761), using `string.Create()`. – l33t Sep 14 '20 at 14:15
9

The fastest method:

private string Capitalize(string s){
    if (string.IsNullOrEmpty(s))
    {
        return string.Empty;
    }
    char[] a = s.ToCharArray();
    a[0] = char.ToUpper(a[0]);
    return new string(a);
}

Tests show the next results (string with 1,0000,000 symbols as input):

Test results

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
8

Try this:

static public string UpperCaseFirstCharacter(this string text) {
    return Regex.Replace(text, "^[a-z]", m => m.Value.ToUpper());
}
JoelFan
  • 37,465
  • 35
  • 132
  • 205
  • 2
    or perhaps some other character class (i.e. alphanumeric \w), so that the function is unicode-aware – Dmitry Ledentsov Aug 26 '13 at 12:51
  • @DmitryLedentsov- C# string class is built on UTF-16 characters. [String Class](https://msdn.microsoft.com/en-us/library/system.string(v=vs.110).aspx) *"Represents text as a sequence of UTF-16 code units."* – ToolmakerSteve Apr 10 '17 at 19:23
  • An explanation would be in order. E.g., what is the gist/idea? Please respond by [editing your answer](https://stackoverflow.com/posts/11974260/edit), not here in comments (***without*** "Edit:", "Update:", or similar - the answer should appear as if it was written today). – Peter Mortensen Jul 12 '21 at 19:49
  • 1
    The best and smallest answer! – Hossein Amini Nov 09 '21 at 08:42
8

Check if the string is not null, convert the first character to upper case and the rest of them to lower case:

public static string FirstCharToUpper(string str)
{
    return str?.First().ToString().ToUpper() + str?.Substring(1).ToLower();
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
mbadeveloper
  • 1,272
  • 9
  • 16
7

If performance/memory usage is an issue then, this one only creates one (1) StringBuilder and one (1) new String of the same size as the original string.

public static string ToUpperFirst(this string str) {
  if(!string.IsNullOrEmpty(str)) {
    StringBuilder sb = new StringBuilder(str);
    sb[0] = char.ToUpper(sb[0]);

    return sb.ToString();

  } else return str;
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Daniel Halan
  • 584
  • 7
  • 8
  • 4
    This could be done with a simple `char[]` rather than having all the infrastructure of a `StringBuilder` wrap it. Instead of `new StringBuilder(str)`, use `str.ToCharArray()`, and instead of `sb.ToString()`, use `new string(charArray)`. `StringBuilder` emulates the type of indexing that a character array exposes natively, so the actual `.ToUpper` line can be essentially the same. :-) – Jonathan Gilbert Nov 17 '16 at 18:49
  • [Darren](http://stackoverflow.com/a/27073919/199364) (a year later) shows how to do this using `ToCharArray`, as suggested by @JonathanGilbert – ToolmakerSteve Apr 10 '17 at 20:38
6

Since I happened to be working on this also, and was looking around for any ideas, this is the solution I came to. It uses LINQ, and will be able to capitalize the first letter of a string, even if the first occurrence isn't a letter. Here's the extension method I ended up making.

public static string CaptalizeFirstLetter(this string data)
{
    var chars = data.ToCharArray();

    // Find the Index of the first letter
    var charac = data.First(char.IsLetter);
    var i = data.IndexOf(charac);

    // capitalize that letter
    chars[i] = char.ToUpper(chars[i]);

    return new string(chars);
}

I'm sure there's a way to optimize or clean this up a little bit.

CAOakley
  • 1,142
  • 1
  • 10
  • 8
6

If you only care about the first letter being capitalized and it does not matter the rest of the string, you can just select the first character, make it upper case and concatenate it with the rest of the string without the original first character.

String word ="red house";
word = word[0].ToString().ToUpper() + word.Substring(1, word.length -1);
//result: word = "Red house"

We need to convert the first character ToString(), because we are reading it as a Char array, and the Char type does not have a ToUpper() method.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
5

Here's a way to do it as an extension method:

static public string UpperCaseFirstCharacter(this string text)
{
    if (!string.IsNullOrEmpty(text))
    {
        return string.Format(
            "{0}{1}",
            text.Substring(0, 1).ToUpper(),
            text.Substring(1));
    }

    return text;
}

It can then be called like:

//yields "This is Brian's test.":
"this is Brian's test.".UpperCaseFirstCharacter();

And here are some unit tests for it:

[Test]
public void UpperCaseFirstCharacter_ZeroLength_ReturnsOriginal()
{
    string orig = "";
    string result = orig.UpperCaseFirstCharacter();

    Assert.AreEqual(orig, result);
}

[Test]
public void UpperCaseFirstCharacter_SingleCharacter_ReturnsCapital()
{
    string orig = "c";
    string result = orig.UpperCaseFirstCharacter();

    Assert.AreEqual("C", result);
}

[Test]
public void UpperCaseFirstCharacter_StandardInput_CapitalizeOnlyFirstLetter()
{
    string orig = "this is Brian's test.";
    string result = orig.UpperCaseFirstCharacter();

    Assert.AreEqual("This is Brian's test.", result);
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
bingles
  • 11,582
  • 10
  • 82
  • 93
5

I found something in C# Uppercase First Letter - Dot Net Perls:

static string UppercaseFirst(string s)
{
    // Check for empty string.
    if (string.IsNullOrEmpty(s))
    {
        return string.Empty;
    }

    // Return char and concat substring.
    return char.ToUpper(s[0]) + s.Substring(1);
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Zameer Ansari
  • 28,977
  • 24
  • 140
  • 219
3

This will do it although it will also make sure that there are no errant capitals that are not at the beginning of the word.

public string(string s)
{
    System.Globalization.CultureInfo c = new System.Globalization.CultureInfo("en-us", false)
    System.Globalization.TextInfo t = c.TextInfo;

    return t.ToTitleCase(s);
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Jeff Hornby
  • 12,948
  • 4
  • 40
  • 61
2

We can do this (C# 8.0, .NET 5):

input?.Length > 0 ? char.ToUpperInvariant(input[0]) + input[1..] : input

I believe that is short enough to do inline.


If input is an empty string, we get an empty string. If input is null, we get null.

Otherwise, the code takes the first character input[0] and convert it to uppercase with char.ToUpperInvariant. And concatenate the rest input[1..].

The compiler will convert the range access to a call to Substring, plus it can take advantage of the fact that we already got the length.

Over the accepted answer, this has the advantage of not using LINQ. Some other answers convert the string to array just to take the first character. This code does not do that either.


If you prefer an extension method, you can do this:

public static string FirstCharToUpper(this string input) =>
        input?.Length > 0 ? char.ToUpperInvariant(input[0]) + input[1..] : input;

What if you prefer to throw? OK, have it throw:

public static string FirstCharToUpper(this string input) =>
        input switch
        {
            null => throw new ArgumentNullException(nameof(input)),
            _ => input.Length > 0 ? char.ToUpperInvariant(input[0]) + input[1..] : input
        };

Here roughly equivalent code (since we are making an extension method, we can be a bit more verbose):

public static string FirstCharToUpperEquivalent(this string input)
{
    if (input == null)
    {
        throw new ArgumentNullException(nameof(input));
    }

    var length = input.Length;
    if (length == 0)
    {
        return input;
    }

    string firstCharacter = char.ToUpperInvariant(input[0]).ToString();
    return string.Concat(firstCharacter, input.Substring(1, length - 1));
}

I did a benchmark with 1000 rounds of 155 words (So they were called 155000 times), and this is the result:

Benchmarking type Tests
  TestAccepted         00:00:00.0465979
  TestProposalNoThrow  00:00:00.0092839
  TestProposalDoThrow  00:00:00.0092938
  TestProposalEquival  00:00:00.0091463

I ran it on Windows 10, Intel Core i3, using the code from Simple microbenchmarking in C# by Jon Skeet.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Theraot
  • 31,890
  • 5
  • 57
  • 86
1
string emp="TENDULKAR";
string output;
output=emp.First().ToString().ToUpper() + String.Join("", emp.Skip(1)).ToLower();
Shailesh
  • 980
  • 8
  • 16
  • Why ToLower() at the tail?. There is no requirement for other letters but the first one. – Carlos Muñoz Oct 22 '13 at 16:41
  • `String` is can be anything its `Upper` or `Lower`.so its a generic solution for all string. – Shailesh Nov 11 '13 at 04:55
  • Why `Join` instead of `emp.First().ToString().ToUpper() + emp.Substring(1);`? Probably need to be more defensive too: `output = string.IsNullOrEmpty(emp) ? string.Empty : [...]`. Also, fwiw, agree with @CarlosMuñoz -- you don't need the `ToLower()` for the OP's question. – ruffin Aug 18 '15 at 19:17
  • @ ruffin--> using `Substring` is also good writing style of code,I agree your solution to trim a code but in this case writing a `ToLower()` is good programing practice.`string` can be anything In `Upper` case or `Lower` case depends upon user input, i give a generic solution. – Shailesh Sep 23 '15 at 12:19
  • 1
    @Shailesh - However, the question did **not** request that **only** the first letter be a capital. It asked that the first letter be changed to be a capital. Without further clarification from author, the most natural assumption is that the remainder of the string be unchanged. Given that you are answering *three years later*, please assume that the *accepted answer* does what asker requested. Only give a different answer if there is some technical reason to do it differently. – ToolmakerSteve Apr 10 '17 at 19:40
1

There seems to be a lot of complexity here when all you need is:

/// <summary>
/// Returns the input string with the first character converted to uppercase if a letter
/// </summary>
/// <remarks>Null input returns null</remarks>
public static string FirstLetterToUpperCase(this string s)
{
    if (string.IsNullOrWhiteSpace(s))
        return s;

    return char.ToUpper(s[0]) + s.Substring(1);
}

Noteworthy points:

  1. It's an extension method.

  2. If the input is null, empty or white space the input is returned as is.

  3. String.IsNullOrWhiteSpace was introduced with .NET Framework 4. This won't work with older frameworks.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Stephen Kennedy
  • 20,585
  • 22
  • 95
  • 108
  • 2
    I don't see how this is an improvement on the original accepted answer from four years ago. In fact, it is *inconsistent* (harmlessly so, but four years late, I have high standards for a new answer adding benefit): The only benefit of using the newer `IsNullOrWhiteSpace` rather than `IsNullOrEmpty`, is if you are going to *find and **change** the first non-white-space*. But you don't - you always operate on `s[0]`. So its pointless [both semantically and performance] to use `IsNullOrWhiteSpace`. – ToolmakerSteve Apr 10 '17 at 19:50
  • 1
    ... why this usage of `IsNullOrWhiteSpace` troubles me, is that a careless reader might think "He checked for white space, so the following code really does find and change a letter, even if it is preceded by white space". Since your code will fail to change a "first" letter preceded by white space, using `IsNullOrWhiteSpace` can only *mislead* a reader. – ToolmakerSteve Apr 10 '17 at 19:56
  • ... oops, I don't mean the accepted answer, I mean [Equiso's answer](http://stackoverflow.com/a/4135491/199364) from the same time period. – ToolmakerSteve Apr 10 '17 at 20:04
1

This is the fastest way:

public static unsafe void ToUpperFirst(this string str)
{
    if (str == null)
        return;
    fixed (char* ptr = str)
        *ptr = char.ToUpper(*ptr);
}

Without changing the original string:

public static unsafe string ToUpperFirst(this string str)
{
    if (str == null)
        return null;
    string ret = string.Copy(str);
    fixed (char* ptr = ret)
        *ptr = char.ToUpper(*ptr);
    return ret;
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Anonymous
  • 51
  • 3
  • Welcome to Stack Overflow! While this code may answer the question, it would be better to include some context and explain how it works. That last line has a lot going on, so why does this lead to maximum performance? – ryanyuyu Aug 13 '15 at 16:39
  • @ryanyuyu this way is fastest, because: 1) Only one function call (`char.ToUpper()`) 2) It's modify original string without creating three or more unnecessary strings as in other answers – Anonymous Aug 13 '15 at 17:04
  • It it probably quite fast, however it is unsafe and not just because it uses the "unsafe" keyword. Say you have multiple string variables with the same string value in them and you use this to modify one of the strings, all of the strings are modified. i.e `var a = "hello"; var b = "hello; a.ToUpperFirst()` you will find that the b value has also been changed. – Grax32 Aug 13 '15 at 17:04
  • @Grax only if refs are equal `var a = new string("hello".ToCharArray()); var b = new string("hello".ToCharArray()); a.ToUpperFirst();` – Anonymous Aug 13 '15 at 17:20
  • 2
    @Anonymous please [edit] that into your post instead of just commenting. – ryanyuyu Aug 13 '15 at 18:09
  • 2
    To expand of Grax's comment, it's because of how C# interns strings. So the references really might be equal. – ryanyuyu Aug 13 '15 at 18:13
  • 3
    Not just interning. Strings are supposed to be, and assumed to be by all .NET code, immutable. *Any* situation where two variables point at the same underlying `System.String` object would see the string change out from under it. Consider if a given `System.String` object is used as a key in a `Dictionary` -- the string's hash could suddenly be incorrect, putting the value in the wrong bucket and corrupting the data structure. The second version is the only "safe" version to use, and even it is technically violating the runtime's assumptions and the CLR specification. – Jonathan Gilbert Nov 17 '16 at 19:00
  • 1
    Don't use either of these approaches. Approach #1: Violating the immutability of the built-in `string` class is unacceptable - a violation of sane coding principles. If programmer wants a mutable string, they should build a custom class around `char[]`. Approach #2: No need to do `unsafe` programming to accomplish this. See [Darren's answer](http://stackoverflow.com/a/27073919/199364) which does the equivalent, using `ToCharArray`. – ToolmakerSteve Apr 10 '17 at 20:30
1

I wanted to provide a "maximum performance" answer. In my mind, a "maximum performance" answer catches all scenarios and provides the answer to the question accounting for those scenarios. So, here is my answer. With these reasons:

  1. IsNullOrWhiteSpace accounts for strings that are just spaces or null/empty.

  2. .Trim() removes white space from the front and back of the string.

  3. .First() takes the first element of an IEnumerable<TSource> (or string).

  4. We should check to see if it is a letter that can/should be uppercase.

  5. We then add the rest of the string, only if the length indicates we should.

  6. By .NET best practice, we should provide a culture under System.Globalization.CultureInfo.

  7. Providing them as optional parameters makes this method totally reusable, without having to type the chosen culture every time.

  8. I also noticed that my and most of these answers did not maintain the whitespace at the beginning of the string. This will also show how to maintain that whitespace.

    //Capitalize the first letter disregard all chars using regex.
    public static string RegCapString(this string instring, string culture = "en-US", bool useSystem = false)
    {
        if (string.IsNullOrWhiteSpace(instring))
        {
            return instring;
        }
        var m = Regex.Match(instring, "[A-Za-z]").Index;
        return instring.Substring(0, m) + instring[m].ToString().ToUpper(new CultureInfo(culture, useSystem)) + instring.Substring(m + 1);
    }
    //Capitalize first char if it is a letter disregard white space.
    public static string CapString(this string instring, string culture = "en-US", bool useSystem = false)
    {
        if (string.IsNullOrWhiteSpace(instring) ||
           !char.IsLetter(instring.Trim().First()))
        {
            return instring;
        }
        var whiteSpaces = instring.Length - instring.TrimStart().Length;
        return (new string(' ', whiteSpaces)) + 
            instring.Trim().First().ToString().ToUpper(new CultureInfo(culture, useSystem)) + 
            ((instring.TrimStart().Length > 1) ? instring.Substring(whiteSpaces + 1) : "");
    }
    
Patrick Knott
  • 1,666
  • 15
  • 15
  • 3
    While this covers most cases, wouldn't it be rather slow considering the number of strings being created with each operation? There is a ton of string allocation going on here. Preferably it would be allocated once, and only once. – Douglas Gaskell Aug 10 '18 at 00:45
  • "ienumerable" doesn't seem right. Isn't it spelled differently? – Peter Mortensen Jul 12 '21 at 20:32
  • sorry, @PeterMortensen yes, it is correct when it is capitalized it will look right. – Patrick Knott Aug 04 '21 at 20:19
  • @DouglasGaskell I changed my answer to include the regex for a very simple answer. I also condensed my original method, reducing the number of string assignments per your comment. You can see my original answer in edit history. – Patrick Knott Aug 04 '21 at 21:32
1

I think the below method is the best solution.

class Program
{
    static string UppercaseWords(string value)
    {
        char[] array = value.ToCharArray();
        // Handle the first letter in the string.
        if (array.Length >= 1)
        {
            if (char.IsLower(array[0]))
            {
                array[0] = char.ToUpper(array[0]);
            }
        }
        // Scan through the letters, checking for spaces.
        // ... Uppercase the lowercase letters following spaces.
        for (int i = 1; i < array.Length; i++)
        {
            if (array[i - 1] == ' ')
            {
                if (char.IsLower(array[i]))
                {
                    array[i] = char.ToUpper(array[i]);
                }
            }
        }
        return new string(array);
    }

    static void Main()
    {
        // Uppercase words in these strings.
        const string value1 = "something in the way";
        const string value2 = "dot net PERLS";
        const string value3 = "String_two;three";
        const string value4 = " sam";
        // ... Compute the uppercase strings.
        Console.WriteLine(UppercaseWords(value1));
        Console.WriteLine(UppercaseWords(value2));
        Console.WriteLine(UppercaseWords(value3));
        Console.WriteLine(UppercaseWords(value4));
    }
}

Output

Something In The Way
Dot Net PERLS
String_two;three
 Sam

Reference

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
D.JCode
  • 386
  • 2
  • 12
1

Possible solution to resolve your problem:

   public static string FirstToUpper(this string lowerWord)
   {
       if (string.IsNullOrWhiteSpace(lowerWord) || string.IsNullOrEmpty(lowerWord))
            return lowerWord;
       return new StringBuilder(lowerWord.Substring(0, 1).ToUpper())
                 .Append(lowerWord.Substring(1))
                 .ToString();
   }
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
sayah imad
  • 1,507
  • 3
  • 16
  • 24
1

Here's the code that worked for me:

private string StringLetterUppercase(string input)
{
    if (input == null)
    {
        throw new ArgumentNullException(nameof(input));
    }
    else if (input == "")
    {
        throw new ArgumentException($"{nameof(input)} cannot be empty", nameof(input));
    }
    else
    {
        return input.First().ToString().ToUpper() + input.Substring(1);
    }
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
0

It seems like none of the solutions given here will deal with a white space before the string.

Just adding this as a thought:

public static string SetFirstCharUpper2(string aValue, bool aIgonreLeadingSpaces = true)
{
    if (string.IsNullOrWhiteSpace(aValue))
        return aValue;

    string trimmed = aIgonreLeadingSpaces
           ? aValue.TrimStart()
           : aValue;

    return char.ToUpper(trimmed[0]) + trimmed.Substring(1);
}

It should handle this won't work on other answers (that sentence has a space in the beginning), and if you don't like the space trimming, just pass a false as the second parameter (or change the default to false, and pass true if you want to deal with space)).

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Noctis
  • 11,507
  • 3
  • 43
  • 82
0

FluentSharp has the lowerCaseFirstLetter method which does this.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Dinis Cruz
  • 4,161
  • 2
  • 31
  • 49
0

The following function is correct for all ways:

static string UppercaseWords(string value)
{
    char[] array = value.ToCharArray();
    // Handle the first letter in the string.
    if (array.Length >= 1)
    {
        if (char.IsLower(array[0]))
        {
            array[0] = char.ToUpper(array[0]);
        }
    }
    // Scan through the letters, checking for spaces.
    // ... Uppercase the lowercase letters following spaces.
    for (int i = 1; i < array.Length; i++)
    {
        if (array[i - 1] == ' ')
        {
            if (char.IsLower(array[i]))
            {
                array[i] = char.ToUpper(array[i]);
            }
        }
    }
    return new string(array);
}

I found that here.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
  • 1
    Why? Why add *yet another answer* when there are already so many answers that seem similar? What's wrong with **all** the existing answers, that prompted you to add another one? – ToolmakerSteve Apr 10 '17 at 19:31
  • Because this answare is correct for all ways. Take it easy. –  Apr 11 '17 at 12:26
  • 1
    I am sorry; I was unnecessarily harsh. I'll stick to the facts: 1) This is essentially the same as [thattolleyguy's answer](http://stackoverflow.com/a/4135541/199364) seven years earlier. 2) This has the same flaw as that answer: doesn't handle white space other than blank character. 3) This answers a slightly different question than OP was asking. Use an answer like this if you want **all** words to have first letter capitalized. 4) Usually, the simpler way to accomplish that is to use TitleInfo.ToTitleCase. (On the other hand, an advantage of code sample is can customize as desired.) – ToolmakerSteve Apr 12 '17 at 00:15
  • Correcting myself: This is different than thattolleyguy's approach: it leaves untouched letters that aren't the first letter of the word. Instead, it is a *duplicate* of [zamoldar's answer](http://stackoverflow.com/a/26669988/199364). Favorably, **kudos to Darian for giving the link to the source** - it seems zamoldar plagiarized without giving credit. **Because of providing that source link, and thereby improving the discussion**, I am upvoting this answer, despite my criticism of it. – ToolmakerSteve Apr 12 '17 at 00:48
  • 1
    Darian, two improvements that could be made: 1) use `char.IsWhiteSpace( array[ i -1 ] )` instead of `.. == ' '`, to handle all white space. 2) remove the two places that do `if (char.isLower(..))` - they serve no purpose. `ToUpper` simply does nothing if a character isn't lower case. – ToolmakerSteve Apr 12 '17 at 00:59
  • It's interesting. We have to remember the original question: "... (with maximum performance)" Do you know if char.IsWhiteSpace (array [i -1]) works better than .. == ''?. The second improvement is ok for me, I would like to know what about performance too. –  Apr 13 '17 at 19:37
0

Expanding on Carlos' question above, if you want to capitalize multiple sentences you may use this code:

    /// <summary>
    /// Capitalize first letter of every sentence. 
    /// </summary>
    /// <param name="inputSting"></param>
    /// <returns></returns>
    public string CapitalizeSentences (string inputSting)
    {
        string result = string.Empty;
        if (!string.IsNullOrEmpty(inputSting))
        {
            string[] sentences = inputSting.Split('.');

            foreach (string sentence in sentences)
            {
                result += string.Format ("{0}{1}.", sentence.First().ToString().ToUpper(), sentence.Substring(1)); 
            }
        }

        return result; 
    }
Zamir
  • 79
  • 4
0

Recently I had a similar requirement and remembered that the LINQ function Select() provides an index:

string input;
string output;

input = "red house";
output = String.Concat(input.Select((currentChar, index) => index == 0 ? Char.ToUpper(currentChar) : currentChar));
//output = "Red house"

Since I need that very often I made an extension method for the string type:

public static class StringExtensions
{
    public static string FirstLetterToUpper(this string input)
    {
        if (string.IsNullOrEmpty(input))
            return string.Empty;
        return String.Concat(input.Select((currentChar, index) => index == 0 ? Char.ToUpper(currentChar) : currentChar));
    }
}

Please note that only the first letter is converted to upper case - all remaining characters are not touched. If you need the other characters to be lower case you may also call Char.ToLower(currentChar) for index > 0 or call ToLower() on the whole string in the first place.

Regarding performance I compared the code with the solution from Darren. On my machine Darren's code is about two times faster which is no surprise since he's directly editing only the first letter within a char array.

So I suggest you take Darren's code if you need the fastest solution available. If you want to integrate other string manipulations as well it may be convenient to have the expressive power of a lambda function touching the characters of the input string - you can easily extend this function - so I leave this solution here.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Grimm
  • 690
  • 8
  • 17
  • 1
    I was wondering how I would solve this problem, worked out my own solution, then came back to post it only to find you had come up with the exact same solution I had already. +1 to you! – BlueFuzzyThing Jan 09 '20 at 15:18
0

Too late for the party, but either way, here is my 2 cents:

static string ToTitleCase(string str)
    => string.Concat((char)(str[0] & 0xDF), str[1..]);
Celso Jr
  • 136
  • 10
0

in addition to @Carlos Muñoz I'd say

public static string FirstCharToUpper(this string input) =>
   input switch
   {
      string s when string.IsNullOrWhiteSpace(s) => throw new ArgumentException($"{nameof(input)} cannot be null, empty or whitespace", nameof(input)),
      _ => string.Concat(input[0].ToString().ToUpper(), input.AsSpan(1))
   };
bo bac
  • 11
  • 3
-1

Use the following code:

string strtest ="PRASHANT";
strtest.First().ToString().ToUpper() + strtest.Remove(0, 1).ToLower();
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
  • 1
    Its not even worth a point to my rep to downvote this answer added years later, that is obviously equivalent to already existing answers. If you are going to add a new answer to a question with many answers, please explain *what you believe is superior* about your answer, or *under what circumstances* your answer would be more useful than other answers. Be specific. – ToolmakerSteve Apr 10 '17 at 20:10
-1

This capitalizes the first letter and every letter following a space and lower cases any other letter.

public string CapitalizeFirstLetterAfterSpace(string input)
{
    System.Text.StringBuilder sb = new System.Text.StringBuilder(input);
    bool capitalizeNextLetter = true;
    for(int pos = 0; pos < sb.Length; pos++)
    {
        if(capitalizeNextLetter)
        {
            sb[pos]=System.Char.ToUpper(sb[pos]);
            capitalizeNextLetter = false;
        }
        else
        {
            sb[pos]=System.Char.ToLower(sb[pos]);
        }

        if(sb[pos]=' ')
        {
            capitalizeNextLetter=true;
        }
    }
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
thattolleyguy
  • 805
  • 6
  • 11
  • 2
    Or if you don't want to write walls of code - CultureInfo.CurrentCulture.TextInfo.ToTitleCase(theString); does the same thing. – CatDadCode Nov 09 '10 at 15:48
  • Yeah... I didn't know about that :) And due to my massive amount of code, everyone else's answers popped up while I was still typing. – thattolleyguy Nov 09 '10 at 15:51
  • 1
    UPVOTED: 1) A slight difference between this answer and ToTitleCase, is that this answer forces words that are all caps to become TitleCase, whereas ToTitleCase leaves such words alone (assumes they might be acronyms). This might or might not be what is desired. **An advantage of having a code example like this, is that it can be modified as desired.** 2) this won't handle white space other than ' ' correctly. should replace blank test with white space test. – ToolmakerSteve Apr 12 '17 at 00:06
-1

This also works, using Take, Skip and Aggregate:

    public static string FirstCharToUpper(this string text) 
    {
      if (String.IsNullOrEmpty(text)) return String.Empty;
      var first = text.Take(1).ToArray()[0].ToString().ToUpper();
      var rest = text.Skip(1).Aggregate("", ((xs, x) => xs + x));
      return first + rest;
    }
-2

The easiest way to capitalize the first letter is:

  1. Using System.Globalization;

     // Creates a TextInfo based on the "en-US" culture.
     TextInfo myTI = new CultureInfo("en-US", false).
    
     myTI.ToTitleCase(textboxname.Text)
    
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Saad Khalid
  • 88
  • 1
  • 10
  • 4
    This answer is essentially identical to answers given *years* earlier. It adds nothing to discussion. – ToolmakerSteve Apr 10 '17 at 19:38
  • 3
    It is also wrong, just like the comment in the other one, this turns every first letter in all words capital not i.e. Red House instead of Red house. – DeadlyChambers Oct 12 '17 at 18:06
-4

As BobBeechey suggests in his response to this question, the following code will work for this:

private void txt_fname_TextChanged(object sender, EventArgs e)
{
    char[] c = txt_fname.Text.ToCharArray();
    int j;
    for (j = 0; j < txt_fname.Text.Length; j++)
    {
        if (j==0) c[j]=c[j].ToString().ToUpper()[0];
        else c[j] = c[j].ToString().ToLower()[0];
    }
    txt_fname.Text = new string(c); 
    txt_fname.Select(txt_fname.Text.Length, 1);
}
Brad Larson
  • 170,088
  • 45
  • 397
  • 571
dhiraj
  • 73
  • 2
  • 14
  • http://itknowledgeexchange.techtarget.com/itanswers/convert-first-letter-to-uppercase/ – dhiraj Aug 16 '12 at 21:36
  • Please explain *how* you believe this to be an *improvement* over answers already posted, years earlier. – ToolmakerSteve Apr 10 '17 at 20:09
  • 3
    .. upon further review, this is a poor answer. 1) `c[j].ToString().ToUpper()[0]` is an inefficient way to do `char.ToUpper(c[j])`. 2) There is other clutter and minor inefficiencies - which wouldn't bother me if this was written at the time the question was posted. But if you are going to add an answer later, *please* make sure it is high quality, and a novel approach, not already covered by existing answers. – ToolmakerSteve Apr 12 '17 at 00:43
-4

With this method you can upper the first character of every word.

Example

"HeLlo wOrld" => "Hello World"

public static string FirstCharToUpper(string input)
{
    if (String.IsNullOrEmpty(input))
        throw new ArgumentException("Error");
    return string.Join(" ", input.Split(' ').Select(d => d.First().ToString().ToUpper() +  d.ToLower().Substring(1)));
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
sebacipo
  • 810
  • 7
  • 9
-4
string input = "red HOUSE";
System.Text.StringBuilder sb = new System.Text.StringBuilder(input);

for (int j = 0; j < sb.Length; j++)
{
    if ( j == 0 ) //catches just the first letter
        sb[j] = System.Char.ToUpper(sb[j]);
    else  //everything else is lower case
        sb[j] = System.Char.ToLower(sb[j]);
}
// Store the new string.
string corrected = sb.ToString();
System.Console.WriteLine(corrected);
jcolebrand
  • 15,889
  • 12
  • 75
  • 121
-4

I use this to correct names. It basically works on the concept of changing a character to uppercase if it follows a specific pattern. In this case I've gone for space and dash of "Mc".

private String CorrectName(String name)
{
    List<String> StringsToCapitalizeAfter = new List<String>() { " ", "-", "Mc" };
    StringBuilder NameBuilder = new StringBuilder();
    name.Select(c => c.ToString()).ToList().ForEach(c =>
    {
        c = c.ToLower();
        StringsToCapitalizeAfter.ForEach(s =>
        {
            if(String.IsNullOrEmpty(NameBuilder.ToString()) ||
               NameBuilder.ToString().EndsWith(s))
            {
                c = c.ToUpper();
            }
        });
        NameBuilder.Append(c);
    });
    return NameBuilder.ToString();
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
-6
 private string capitalizeFirstCharacter(string format)
 {
     if (string.IsNullOrEmpty(format))
         return string.Empty;
     else
         return char.ToUpper(format[0]) + format.ToLower().Substring(1);
 }
JustSomeGuy
  • 3,677
  • 1
  • 23
  • 31
  • 3
    Welcome to StackOverflow. While sometimes posting code is useful, it's better to include a commentary on what the code does and how it answers the question. – wjl Feb 25 '15 at 18:15
  • 4
    This does capitalize the first character, but also un-capitalize the rest of the text, which probably isn't the desired effect. – caiosm1005 Mar 31 '16 at 14:05
  • 4
    Its also equivalent to answers posted years earlier, so in no case does it constribute to the discussion. – ToolmakerSteve Apr 10 '17 at 20:07
-7

The simplest and fastest way is to replace the first character of the string by making it an upper case character:

string str = "test";<br>
str = str.Replace(str[0], char.ToUpper(str[0]));
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
  • This answer is wrong because it blindly updates any instance of the first letter. `"red horse"` becomes `"Red hoRse"` – Marie Nov 12 '19 at 17:49
-7
string s_Val = "test";
if (s_Val != "")
{
   s_Val  = char.ToUpper(s_Val[0]);
   if (s_Val.Length > 1)
   {
      s_Val += s_Val.Substring(1);
   }
 }
Sebastien Robert
  • 331
  • 4
  • 11
  • 5
    What if the string is only 0 or 1 character long? – GvS Nov 09 '10 at 15:33
  • 6
    This is just wrong. Firstly it wont compile as you are trying to write a char back into the original string. Secondly if you add ToString to line 4 to make it compile the result is always just the first char as a capital and lines 5-8 become unreachable code. – CeejeeB Jan 21 '15 at 10:31