отделить первое отчество фамилию C#

Цель: анализировать имя, когда пользователь вводит имя, и отображать окно сообщения с первым отчеством и фамилией. Прямо сейчас это работает только тогда, когда вы вводите три имени, если вы попробуете два, произойдет сбой, и я уверен, что это причина моего массива, но я не уверен, где я ошибаюсь. Супер новичок, учусь самостоятельно, поэтому любая помощь будет принята с благодарностью!

P.S. Графический интерфейс, который видит пользователь, — это просто блок ввода для ввода своего имени в одну строку с интервалом между каждым словом.

 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);

person Austin D    schedule 29.07.2017    source источник
comment
Вы предположили, что введенное имя состоит из трех частей. Но вы говорите только о двух. Прежде чем продолжить, вы должны увидеть количество элементов в массиве. Если я поставлю первое последним, то их будет только два. Индекс 0 и 1. Таким образом, индекс 2 вызовет сбой.   -  person Andrew Truckle    schedule 29.07.2017
comment
Кроме того, если вам нужна определенная буква, просто используйте оператор [n].   -  person Andrew Truckle    schedule 29.07.2017
comment
Я не думаю, что еще узнал об операторе [n], не видел его раньше. Я супер новичок, и я медленно работаю над некоторыми материалами для самопомощи. Что я могу добавить/удалить, чтобы он проверял только последний индекс для записи, а если его нет, он пропускал его? Или это невозможно?   -  person Austin D    schedule 29.07.2017
comment
Я сейчас не за компом. Можно посмотреть позже.   -  person Andrew Truckle    schedule 29.07.2017
comment
Вы имеете в виду операторы if? Эти длины?   -  person Austin D    schedule 29.07.2017
comment
Если сначала должно быть if (names.length › 0), чтобы вы знали, что у вас есть хотя бы один элемент. Посмотрите пример класса, который кто-то предоставил в своем ответе. Вы правильно проверяете токен строки, но сначала не проверяете фактический массив. Оберните каждую секцию в if, как указано выше.   -  person Andrew Truckle    schedule 29.07.2017
comment
Ваше здоровье! Спасибо! :D Это сделало это!   -  person Austin D    schedule 29.07.2017
comment
Будем надеяться, что Жан-Клод Ван Дамм никогда не войдет в систему.   -  person Enigmativity    schedule 29.07.2017


Ответы (4)


Вам нужно проверить и обработать пустое второе имя. Инициализация строки предотвратит сбой, а затем проверка ввода.

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

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

На самом деле стоило бы инициализировать все ваши переменные или управлять проверкой пользовательского ввода.

person Community    schedule 29.07.2017
comment
Спасибо! :D Это очень помогло! - person Austin D; 29.07.2017
comment
Как видите, если проверка была реализована. ???? - person Andrew Truckle; 29.07.2017
comment
Но если часть состоит только из одного символа, то все равно произойдет сбой. Если нужно два если. Внешний и внутренний. - person Andrew Truckle; 29.07.2017
comment
Но будете ли вы повторять первую букву? Извините, если я ошибаюсь. - person Andrew Truckle; 29.07.2017

Вот рабочий пример, как вы можете это сделать:

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();
    }
}

Пример использования:

class Program
{
    static void Main(string[] args)
    {
        var fullName = new FullName("first middle last");
        Console.WriteLine(fullName);
        Console.ReadLine();
    }
}
person Vano Maisuradze    schedule 29.07.2017
comment
Хороший. Я бы изменил метод ToString. Вы хотите добавить только вторую часть или часть 3, если она не пуста. В противном случае вы получите кленовые пространства. - person Andrew Truckle; 29.07.2017
comment
Также я думаю, что вы должны объяснить, почему его не удалось. В своих комментариях я пытаюсь донести это до него, чтобы он понял, почему его код не удался, а не просто предоставил решение. Мы не хотим просто дать им рыбу. Мы хотим научить их ловить рыбу. ????Он может вставить ваш код. Но замечает ли он, почему у вас работает. Это сделало бы ваш ответ более полным. - person Andrew Truckle; 29.07.2017
comment
Для fullname = "Firstname Lastname" это решение установит для Lastname значение MiddleName, где, я полагаю, Lastname должно перейти к LastName, а MiddleName останется пустым. - person Fabio; 29.07.2017
comment
@Fabio Это не было требованием :) В противном случае я бы сделал его более настраиваемым. - person Vano Maisuradze; 29.07.2017
comment
:) Извините, но тогда имена свойств в вашем классе вводят в заблуждение. Тогда должно быть NameOne, NameTwo, NameThree ;) - person Fabio; 29.07.2017
comment
Кроме того, OP необходимо использовать заглавные буквы, делать первую букву прописной, а другую - строчной, если ваш подход игнорирует это требование;). - person Fabio; 29.07.2017
comment
Возможно, он не поддерживает разные стратегии парсинга, но это не значит, что имена вводят в заблуждение. Вы можете добавить столько функций, сколько хотите, я просто дал ему идею, как он мог это написать. - person Vano Maisuradze; 29.07.2017

Как упоминалось в другом ответе, вам нужно назначать отчество только тогда, когда существует третье имя.
Ниже подход, который использует метод Dictionary.TryGetValue и функцию C # 7 для параметров out.

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());
person Fabio    schedule 29.07.2017
comment
Вместо написания своей версии Capitalize вы можете использовать ToTitleCase() stackoverflow.com/questions/913090 - person Vano Maisuradze; 29.07.2017

Я знаю, что на ваш вопрос был дан ответ, и есть много способов справиться с этим, но вот мое предложение с некоторыми пояснениями по пути:

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);
    }
}

В этом примере не используются все переменные. И он использует оператор [].

Надеюсь, это поможет и вам... :)

person Andrew Truckle    schedule 29.07.2017