-2

I am trying to figure out how to sort input names to right capitalization eg: tim jAmes = Tim James

I have sorted it up to where i can take in the name, but the sorting out has been doing my head in, not very familiar with c# yet but i need this for a test i am doing .

Here's my exisiting code:

Console.WriteLine("What is your name?");
var str = Console.ReadLine();

Console.WriteLine("Hello there, " + str);
tymtam
  • 31,798
  • 8
  • 86
  • 126
6odfrey
  • 11
  • 2
  • 1
    The code you've posted simple prints whatever the user inputs, with no modification at all. Have you made an attempt to solve your problem? You need to be very explicit about the rules for transforming values. I can think of many edge cases. – gunr2171 Mar 31 '22 at 23:21
  • 1
    Enjoy this 13 yr old question which answers tour question: [Converting string to title case](https://stackoverflow.com/questions/1206019/converting-string-to-title-case) Easily found feeding `c# string proper case` to any worthwhile search engine – Ňɏssa Pøngjǣrdenlarp Mar 31 '22 at 23:25
  • While I agree that Title Case is probably what the OP is actually going to use (and I would add my close vote to it if I didn't already commit it), it's not a 100% correct way to capitalize names, such as any name that has two capital letters like "Danny McBride". – gunr2171 Mar 31 '22 at 23:27
  • This can be easily handled with the following code: `Console.WriteLine("What is your name? Please use proper casing.");` Jokes aside, what is your definition of a "name" (first? last? both? more? can either be hyphenated?) and how does it become "properly case"d? Once you specify all that you might find it's not so straightforward. – Lance U. Matthews Mar 31 '22 at 23:28
  • Better duplicates: [How do I capitalize first letter of first name and last name in C#?](https://stackoverflow.com/q/72831/150605) and [How to capitalize names](https://stackoverflow.com/q/5057793/150605) – Lance U. Matthews Apr 01 '22 at 01:10

3 Answers3

0

This is a simple approach:

Console.WriteLine("What is your name?");
var str = Console.ReadLine();

TextInfo textInfo = new CultureInfo("en-US", false).TextInfo;
str = textInfo.ToTitleCase(str); 
Console.WriteLine("Hello there, " + str); //Hello there, Tim James

Just make sure that you include: using System.Globalization; at the top

Wet_Pantz
  • 237
  • 1
  • 5
  • 19
  • 2
    Note that, of course, the method is `ToTitleCase()` and not `ToNameCase()`. And if the user enters `"TIM JAMES"` it won't do anything because, as the documentaton states, such words "are considered to be acronyms." – Lance U. Matthews Mar 31 '22 at 23:32
0

You can roll your own by using static methods of the char class.

The idea is to only capitalize characters that are preceded by a non letter character. This is a naive way of approaching this, but fun to tinker around with.

var input = "TIM JAMES";
var output = "";
var thisChar = ' ';
var shouldCapitalize = true;

for (int i = 0; i < input.Length; i++)
{
    thisChar = input[i];

    if (!char.IsLetter(thisChar)) 
    {
        shouldCapitalize = true;
    }
    else
    {
        if (shouldCapitalize)
        {
            thisChar = char.ToUpper(thisChar);
            shouldCapitalize = false;
        }
        else
        {
            thisChar = char.ToLower(thisChar);
        }
    }

    output += thisChar;
}

Console.WriteLine("Hello there, " + output);

To handle Mc names, eg. McDonuts, you can do the following.

private bool IsMcName(string output, int index, char currentChar)
{
    return
        index > 0 &&
        char.ToLower(currentChar) == 'c' &&
        output[index - 1] == 'M';
}

and call this function from the else statement where the current char is converted to lower case.

else
{
    if (IsMcName(output, i, thisChar))
    {
        shouldCapitalize = true;
    }

    thisChar = char.ToLower(thisChar);
}

I made a similar function for Mac names, eg MacDonuts, and it works.. however I believe it would interfere more times than help. eg. Macy becomes MacY.

private bool IsMacName(string output, int index, char currentChar)
{
    return
        index > 1 &&
        char.ToLower(currentChar) == 'c' &&
        output[index - 1] == 'a' &&
        output[index - 2] == 'M';
}

This can be used in-place, or in-conjunction with, the McName function. eg. if (McName(..) || MacName(..))

hijinxbassist
  • 3,667
  • 1
  • 18
  • 23
  • this was very helpful. I included a line to intake the username and sort it into the "proper case" – 6odfrey Apr 01 '22 at 00:47
  • HI THANK you for this earlier response. I just need to clarify , what can i do to factor exceptions where there's a hyphen in the name since it wont be recorded as a whteSpace? eg Tim Jones-smith should read Tim Jones-Smith etc ? – 6odfrey Apr 06 '22 at 21:55
  • Any additional rules you want to add can be appended as OR statements in the first if statement. eg. `if (char.IsWhiteSpace(thisChar) || !char.IsLetter(thisChar))` etc. You can replace your existing with this and it will capitalize after all non-letter chars (i believe you could remove the IsWhiteSpace check!) – hijinxbassist Apr 06 '22 at 22:02
  • this indeed worked ! my final question (i promise) if say an Irish name as well, Mcsmith should print like McSmith do i append this in the first statement or create a seperate extension ? – 6odfrey Apr 06 '22 at 22:42
  • this indeed worked ! my final question (i promise) if say an Irish name as well, Mcsmith should print like McSmith do i append this in the first statement or create a seperate extension ? – 6odfrey Apr 06 '22 at 22:43
  • That one is a bit different since you need to check a series of chars. You could do something like.. `if (thisChar == 'c' && i > 0 && output[i - 1]) == 'M')`. since we need to check the previous char, you need to make sure you wont go below 0. You could also make a new variable for `prevChar` and assign it at the end of the loop with `prevChar = thisChar`. Then you dont need to check i and can directly compare `M` against prevChar – hijinxbassist Apr 06 '22 at 22:45
  • right - i'll tinker with this and see how it goes. I am truly grateful for your help. – 6odfrey Apr 06 '22 at 23:11
  • You are very welcome. Best of luck – hijinxbassist Apr 06 '22 at 23:13
  • Okay, i am still struggling with this over an hour. Getting an error, maybe its something im missing. I am failing to fit the additional lines of code to the synthax to do the check for the Irish format names,. is there a way you could add to the synthax above to reflect this for me to see? (I am sorry i may come across a nag, still fairly new with c# and trying to just complete an assessment) – 6odfrey Apr 07 '22 at 00:23
0

This cannot be done reliably because there are just many different kind of names that don't follow the basic rule with the first letter being capital followed by lowercase letters. One example is Neil deGrasse Tyson.

You may try ToTitleCase as others suggested - and this even covers , but if you doing this as an exercise to learn programming you could go back to basics and try with Split and ToLower and ToUpper:

using System.Globalization;

var name = "tim jAmes";

Console.WriteLine($"{name} => {FixName(name)}");

string FixName(string name)
{
    var culture =  new CultureInfo(name: "en-US", useUserOverride: false);

    if( name.ToLower() == "Neil deGrasse Tyson".ToLower())
    {
        return "Neil deGrasse Tyson"; // ;)
    }

    var parts = name.Split(" ");
    var fixedParts = new List<string>();
    foreach(var part in parts)
    {
        var fixedPart = char.ToUpper(part[0], culture) 
                      + part.Substring(startIndex: 1).ToLower(culture);
        fixedParts.Add(fixedPart);
    }

    var fixedName = string.Join(" ", fixedParts);
    return fixedName;
}

This prints:

tim jAmes => Tim James
tymtam
  • 31,798
  • 8
  • 86
  • 126