Morpheus_God
@Morpheus_God

Как правильно реализовать разделение входящей строки на аргументы?

Добрый день.
Нужна помощь с правильным написанием функции для указании команд боту Steam.
Принцип следующий, человек пишет
!send после этой команды надо подхватить слово и передать его в функцию которая будет выполнять нужное действие.
!buy после этого имя игры которое передать в функцию которая купит игру.
Я кое как реализовал, но мне не нравится код, слишком он кажется сложен для чтения и сам потом забуду куда и что. Хочется более изящное решение.
Вот код метода который обрабатывает сообщение от пользователя:
static void OnChatMessage(SteamFriends.FriendMsgCallback callback)
        {
          //calback.Message это получение сообщения для бота.
            string[] args;
            if(callback.EntryType == EChatEntryType.ChatMsg)
            {
                if(callback.Message.Length >1)
                {
                    if(callback.Message.Remove(1) == "!")
                    {
                        string command = callback.Message;
                        if(callback.Message.Contains(" "))
                        {
                            command = callback.Message.Remove(callback.Message.IndexOf(' '));
                        }
                        switch(command)
                        {
                            case "!send":
                                args = Separate(2,' ',callback.Message);
                                Console.WriteLine($"send :{ args[1]} {args[2]} command recieved. User: {steamFriends.GetFriendPersonaName(callback.Sender)}");
                                if(args[0] == "-1")
                                {
                                    steamFriends.SendChatMessage(callback.Sender, EChatEntryType.ChatMsg, "Command syntax !send [friend] [message]");
                                    return;
                                }
                                for(int i = 0; i<steamFriends.GetFriendCount(); i++)
                                {
                                    SteamID friend = steamFriends.GetFriendByIndex(i);
                                    if(steamFriends.GetFriendPersonaName(friend).ToLower().Contains(args[1].ToLower()))
                                    {
                                        steamFriends.SendChatMessage(friend, EChatEntryType.ChatMsg, args[2]);
                                    }
                                }
                                break;
                        }
                    }
                }
            }

Вот код самой функции которая разбивает строку на аргументы.
public static string [] Separate (int number,char separator,string thestring)
        {
            string[] returned = new string[4];
            int i = 0;
            int error = 0;
            int lenght = thestring.Length;

            foreach(char c in thestring)
            {
                if(i !=number)
                {
                    if(error > lenght || number >5)
                    {
                        returned[0] = "-1";
                        return returned;
                    }
                    else if(c==separator)
                    {
                        returned[i] = thestring.Remove(thestring.IndexOf(c));
                        thestring = thestring.Remove(0, thestring.IndexOf(c) + 1);
                        i++;
                    }
                    error++;
                    if(error == lenght && i!=number)
                    {
                        returned[0] = "-1";
                        return returned;
                    }
                }
                else
                {
                    returned[i] = thestring;
                }
            }
            return returned;
        }
  • Вопрос задан
  • 150 просмотров
Решения вопроса 2
yarosroman
@yarosroman Куратор тега C#
C# the best
Первый вопрос, а чем String.Split не удовлетворил?

var commands=callback.message.Split(null);
switch(commands[0])
{
   case "!send":
   case "!bay":
}


или например, если аргумент содержит пробелы

if (command.Contains("!send "))
{
    var arg=command.Remove("!send ");
}
Ответ написан
arxont
@arxont
C# программист
По поводу разбивания строки вам уже сказали выше - про Split.
По поводу
но мне не нравится код, слишком он кажется сложен для чтения и сам потом забуду куда и что

Разбивайте код на функции, выносите как можно больше в отдельные классы-методы, пишите комментарии.

Для примера немного другая реализация вашего кода
private static void Main()
{
    var test = "!send testUser testCommand";

    var parsed = ParseMessage(test);

    var argsMessage = parsed.Args.Split(' ');

    switch (parsed.Command)
    {
         case "send":
                  Command.Send(friend: argsMessage[0], message: argsMessage[1]);
                  break;
         
         case "buy":
                  Command.Buy(nameToBuy: argsMessage[0]);
                  break;

         default:
                  Console.WriteLine("Unknow command");
                  break;
    }
}

private static (string Command, string Args) ParseMessage(string message)
{
    var map = new[] {
         new { Value = "!buy",  Result = ("buy", message.Replace("!buy ", "")) },
         new { Value = "!send", Result = ("send", message.Replace("!send ", ""))  }
		};

    var value = map.Where(e => message.StartsWith(e.Value)
                  ? message.StartsWith(e.Value) : message == e.Value)
                  .Select(e => e.Result)
                  .FirstOrDefault();

    if(string.IsNullOrEmpty(value.Item1)) value = ("Unknow command", "");

    return value;
}

private static class Command
{
    public static void Send(string friend, string message)
    {
         Console.WriteLine($"Fried: {friend}, Message {message}");
    }

    public static void Buy(string nameToBuy)
    {
         Console.WriteLine($"nameToBuy {nameToBuy}");
    }
}
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы