5

Goal: parse name when user enters name, and have a message box display with first middle and last name. Right now it only works when you type in three names, if you try two it crashes, and I'm sure it's cause of my array but Im not sure where I'm wrong. Super novice, learning on my own so any help would be greatly appreciated!!

P.S. GUI the user sees is just an entry block for them to enter their name into one line, spacing between each word.

 private void btnParseName_Click(object sender, System.EventArgs e)
    {
        string fullName = txtFullName.Text;
        fullName = fullName.Trim();

        string[] names = fullName.Split(' ');

        string firstName = "";
        string firstLetter = "";
        string otherFirstLetters = "";
        if (names[0].Length > 0)
        {
            firstName = names[0];
            firstLetter = firstName.Substring(0, 1).ToUpper();
            otherFirstLetters = firstName.Substring(1).ToLower();
        }

        string secondName = "";
        string secondFirstLetter = "";
        string secondOtherLetters = "";
        if (names[1].Length > 0)
         {
            secondName = names[1];
            secondFirstLetter = secondName.Substring(0, 1).ToUpper();
            secondOtherLetters = secondName.Substring(0).ToLower();
         }

        string thirdName = "";
        string thirdFirstLetter = "";
        string thirdOtherLetters = "";
        if (names[2].Length > 0)
        {

            thirdName = names[2];
            thirdFirstLetter = thirdName.Substring(0, 1).ToUpper();
            thirdOtherLetters = thirdName.Substring(0).ToLower();

        }

        MessageBox.Show(
                "First Name:         " + firstLetter + otherFirstLetters + "\n\n" +
                "Middle Name:        " + secondFirstLetter + secondOtherLetters + "\n\n" +
                "Last Name:          " + thirdFirstLetter + thirdOtherLetters);
Austin D
  • 55
  • 1
  • 6
  • You have assumed there is three parts in the name entered. But you refer to only two. You must see what the number of items is in the array before you proceed. If I put "first last" then there is only two. Index 0 and 1. So index 2 will cause a crash. – Andrew Truckle Jul 29 '17 at 05:22
  • Also, it you want a certain letter, just use the [n] operator. – Andrew Truckle Jul 29 '17 at 05:25
  • I don't think I've learned about the [n] operator yet, haven't seen that before. I'm a super novice and I'm slowly working through some self-help material. What can I add/remove to make it only check the last index for an entry and if there isn't one, it skips it? Or is that not possible? – Austin D Jul 29 '17 at 05:29
  • I am not on my pc right now. Can look later. – Andrew Truckle Jul 29 '17 at 05:32
  • You mean in the if statements? Those lengths? – Austin D Jul 29 '17 at 05:35
  • If should be if (names.length > 0) first so that you know you have at least one element. See the sample class someone provided in their answer. You check the string token correctly but you don't first check the actual array. Wrap each section in a if like above. – Andrew Truckle Jul 29 '17 at 05:38
  • 1
    Cheers! Thanks! :D That did it! – Austin D Jul 29 '17 at 05:42
  • 2
    Let's hope that **Jean Claude Van Damme** never logs in. – Enigmativity Jul 29 '17 at 07:09

5 Answers5

5

Here is the working example how you can do it:

public class FullName
{
    public  string FirstName { get; set; }
    public  string MiddleName { get; set; }
    public  string LastName { get; set; }

    public FullName()
    {

    }

    public FullName(string fullName)
    {
        var nameParts = fullName.Split(new [] {' '}, StringSplitOptions.RemoveEmptyEntries);

        if (nameParts == null)
        {
            return;
        }
        if (nameParts.Length > 0)
        {
            FirstName = nameParts[0];
        }
        if (nameParts.Length > 1)
        {
            MiddleName = nameParts[1];
        }
        if (nameParts.Length > 2)
        {
            LastName = nameParts[2];
        }
    }

    public override string ToString()
    {
        return $"{FirstName} {MiddleName} {LastName}".TrimEnd();
    }
}

Usage example:

class Program
{
    static void Main(string[] args)
    {
        var fullName = new FullName("first middle last");
        Console.WriteLine(fullName);
        Console.ReadLine();
    }
}
Vano Maisuradze
  • 5,829
  • 6
  • 45
  • 73
  • 1
    Nice. I would change the ToString method. You only want to add part two and or part 3 if not empty. Other wise you get maple spaces. – Andrew Truckle Jul 29 '17 at 05:26
  • Also I think you should be explaining why his was failing. In my comments I am trying to convey that to him so that he understands specifically why his code failed as opposed to just providing a solution. We don't want to just give them a fish. We want to teach them how to fish. He can paste your code. But does he notice why yours works. That would make your answer more comprehensive. – Andrew Truckle Jul 29 '17 at 05:41
  • For `fullname = "Firstname Lastname"` this solution will set "Lastname" to `MiddleName` where, I suppose, "Lastname" should go to `LastName` and `MiddleName` remain empty. – Fabio Jul 29 '17 at 06:44
  • @Fabio That was not the requirement :) Otherwise I would make it more configurable. – Vano Maisuradze Jul 29 '17 at 06:50
  • 1
    :) Sorry, but then names of the properties in your class are misleading. It should be then `NameOne`, `NameTwo`, `NameThree` ;) – Fabio Jul 29 '17 at 06:52
  • Also, OP need to "capitalize" names, make first letter upper case and other letter lower case, where your approach ignore this requirement ;). – Fabio Jul 29 '17 at 06:56
  • Maybe it does not support different parsing strategies, but it does not mean, that names are misleading. You can add as many feature as you want, I just gave him an idea, how he could write it. – Vano Maisuradze Jul 29 '17 at 07:09
3

You need to check for and handle the second name being empty. Initialising the string will prevent the crash, then checking for input.

string secondName = "";    
string secondFirstLetter = ""; 
string secondOtherLetters = "";

if(names.Length > 2)
{
    secondName = names[1];
    secondFirstLetter = secondName.Substring(0, 1).ToUpper();
    secondOtherLetters = secondName.Substring(0).ToLower();
}

In fact it would be worth intialising all your variables or managing user input validation.

0

As mentioned in another answer you need assign middle name only when third name exists.
Below approach which uses Dictionary.TryGetValue method and C#7 feature for out parameters.

var textInfo = System.Globalization.CultureInfo.CurrentCulture.TextInfo;
var names = fullName.Split(' ')
                    .Where(name => string.IsNullOrWhiteSpace(name) == false)
                    .Select(textInfo.ToTitleCase)
                    .Select((Name, Index) => new { Name, Index })
                    .ToDictionary(item => item.Index, item => item.Name);

names.TryGetValue(0, out string firstName);
names.TryGetValue(1, out string middleName);
if (names.TryGetValue(2, out string lastName) == false)
{
    lastName = middleName;
    middleName = null;
}

// Display result
var result = new StringBuilder();
result.AppendLine("First name: ${firstName}");
result.AppendLine("Middle name: ${middleName}");
result.AppendLine("Last name: ${lastName}");

MessageBox.Show(result.ToString());
Fabio
  • 31,528
  • 4
  • 33
  • 72
0

I know your question has been answered, and there are many ways you could look at handling this, but here is my suggestion with some explanations along the way:

private void button1_Click(object sender, EventArgs e)
{
    string fullName = "Jean Claude Van Dam";
    fullName = fullName.Trim();

    // So we split it down into tokens, using " " as the delimiter
    string[] names = fullName.Split(' ');

    string strFormattedMessage = "";

    // How many tokens?
    int iNumTokens = names.Length;

    // Iterate tokens
    for(int iToken = 0; iToken < iNumTokens; iToken++)
    {
        // We know the token will be at least one letter
        strFormattedMessage += Char.ToUpper(names[iToken][0]);

        // We can't assume there is more letters (they might have used an initial)
        if(names[iToken].Length > 1)
        {
            // Add them (make it lowercase)
            strFormattedMessage += names[iToken].Substring(1).ToLower();

            // Don't need to add "\n\n" for the last token
            if(iToken < iNumTokens-1)
                strFormattedMessage += "\n\n";
        }

        // Note, this does not take in to account names with hyphens or names like McDonald. They would need further examination.
    }

    if(strFormattedMessage != "")
    {
        MessageBox.Show(strFormattedMessage);
    }
}

This example avoids having all of the variables. And it makes use of the operator [].

Hope this helps you too ... :)

Andrew Truckle
  • 17,769
  • 16
  • 66
  • 164
0
 public static string getMiddleName(string fullName)
    {
          var names = fullName.Split(' ');
        string firstName = names[0];
        string middleName = "";// names[1];
        var index = 0;
        foreach (var item in names)
        {
            if (index > 0 && names.Length -1 > index)
            {
                middleName += item + " ";
            }
            index++;
        }
        return middleName;
    }
  • Please don't post only code as an answer, but also provide an explanation what your code does and how it solves the problem of the question. Answers with an explanation are usually more helpful and of better quality, and are more likely to attract upvotes. – Tyler2P Nov 23 '21 at 18:24
  • get middle name by fullname – Jean Carlos Nov 29 '21 at 16:55