You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

外卖店加载程序:文本文件转对象实例解析问题求助

外卖店加载程序解析不完整问题修复

问题背景

开发外卖店加载程序,需将以下格式的文本文件解析为对象实例,实现下单、编辑订单功能:

Name:JustNom FastFood
Toppings:[<cheese,80>,<pepperoni,120>,<tomato sauce,40>,<ham,150>,<mushroom,80>]
Garnishes:[<cheese,100>,<fried onions, 80>,<bacon,150>]
Pizza:<Name:Margherita,Toppings:[tomato sauce, cheese],Price:500>
Pizza:<Name:Ham and Mushroom,Toppings:[tomato sauce, ham, mushroom, cheese],Price:650>
Burger:<Name:Plain Burger,Garnishes:[],Price:350>
Burger:<Name:Cheese Burger,Garnishes:[cheese],Price:450>

现有代码仅能解析第一部分内容(如仅能解析第一个Topping,其余无法解析),尝试循环Load方法未解决,相关代码如下:

原FileReaderMenu代码

namespace JustNom.Logic
{
    internal class FileReaderMenu : MenuItem
    {
        private FileReader _reader;
        public string menuName { get; set; }

        public FileReaderMenu(FileReader reader)
        {
            _reader = reader;
        }

        public override string MenuText()
        {
            return "Select a File.";
        }

        public override void Select()
        {
            StringBuilder sb = new StringBuilder($"{MenuText()}{Environment.NewLine}");
            int i = 1;
            foreach (string file in _reader.paths)
            {
                sb.AppendLine($"{i}. {file}");
                i++;
            }
            Console.WriteLine(sb.ToString());
            int selectedIndex = ConsoleHelpers.GetIntegerInRange(1, _reader.paths.Count, MenuText()) - 1;
            string[] result = File.ReadAllLines(_reader.paths[selectedIndex]);
            if (result.Length == 0)
            {
                Console.WriteLine("Cannot open file - No data found");
            }
            else if (result.Length > 0) 
            {
                var splitedStringList = new List<List<String>>();
                
                Menu menu = new Menu(menuName);

                foreach (string file in result)
                {
                    if (file.StartsWith("Name:"))
                    {
                        menuName = file.Substring("Name:".Length);
                    }
                    string token = file.Substring(0, file.IndexOf(':'));
                    switch (token)
                    {
                        case "Toppings":
                            Topping topping = LoadToppings(file);
                            menu.AddToppings(topping);
                            break;
                        case "Garnishes":
                            Garnish garnish = LoadGarnishes(file);
                            menu.AddGarnish(garnish);
                            break;
                        case "Pizza":
                            Pizza pizza = LoadPizzas(file);
                            menu.AddPizza(pizza);
                            break;
                        case "Burger":
                            Burger burger = LoadBurgers(file);
                            menu.AddBurger(burger);
                            break;
                    }

                    static Topping LoadToppings(string toppings)
                    {
                        int startIndex = toppings.IndexOf('<') + 1;
                        int endIndex = toppings.IndexOf(',');
                        int length = endIndex - startIndex;

                        string name = toppings.Substring(startIndex, length);

                        startIndex = endIndex + 1;
                        endIndex = toppings.IndexOf('>');
                        length = endIndex - startIndex;

                        string price = toppings.Substring(startIndex, length);

                        return new Topping(name, price);
                    }

                    static Garnish LoadGarnishes(string garnishes)
                    {
                        int startIndex = garnishes.IndexOf('<') + 1;
                        int endIndex = garnishes.IndexOf(',');
                        int length = endIndex - startIndex;

                        string name = garnishes.Substring(startIndex, length);

                        startIndex = endIndex + 1;
                        endIndex = garnishes.IndexOf('>');
                        length = endIndex - startIndex;

                        string price = garnishes.Substring(startIndex, length);

                        return new Garnish(name, price);
                    }

                    static Pizza LoadPizzas(string pizza)
                    {
                        int startIndex = pizza.IndexOf(':') + 7;
                        int endIndex = pizza.IndexOf(',');
                        int length = endIndex - startIndex;

                        string name = pizza.Substring(startIndex, length);

                        startIndex = endIndex + 11;
                        endIndex = pizza.IndexOf("]");
                        length = endIndex - startIndex;

                        string toppings = pizza.Substring(startIndex, length);

                        startIndex = endIndex + 1;
                        endIndex = pizza.IndexOf(">>");
                        length = endIndex - startIndex;

                        string price = pizza.Substring(startIndex, length);

                        return new Pizza(name,toppings, price);
                    }

                    static Burger LoadBurgers(string burger)
                    {
                        int startIndex = burger.IndexOf(':') + 7;
                        int endIndex = burger.IndexOf(',');
                        int length = endIndex - startIndex;

                        string name = burger.Substring(startIndex, length);

                        startIndex = burger.IndexOf('[');
                        endIndex = burger.IndexOf("]");
                        length = endIndex - startIndex;
                        
                        string garnish = burger.Substring(startIndex, length);

                        startIndex = burger.IndexOf(':');
                        endIndex = burger.IndexOf(">>");
                        length = endIndex - startIndex;

                        string price = burger.Substring(startIndex, length);

                        return new Burger(name,garnish, price);
                    }
                }
                OrderMenuItem OrderMenu = new OrderMenuItem(menu);
                OrderMenu.MenuText();
            }
        }
    }
}

原Menu类代码

namespace JustNom.JustNom
{
    internal class Menu
    {
        public string Name { get; private set; }
        private List<Burger> _burgers;
        private List<Pizza> _pizzas;
        private List<Garnish> _garnish;
        private List<Topping> _topping;

        public IEnumerable<Burger> Burgers { get { return _burgers; } }
        public IEnumerable<Pizza> Pizzas { get { return _pizzas; } }
        public IEnumerable<Garnish> Garnish { get { return _garnish; } }
        public IEnumerable<Topping> Toppings { get { return _topping; } }

        public Menu(string name)
        {
            Name = name;
            _burgers = new List<Burger>();
            _pizzas = new List<Pizza>();
            _topping = new List<Topping>();
            _garnish = new List<Garnish>();
        }

        public void AddBurger(Burger burger)
        {
            _burgers.Add(burger);
        }

        public void AddPizza(Pizza pizza)
        {
            _pizzas.Add(pizza);
        }

        public void AddGarnish(Garnish garnish)
        {
            _garnish.Add(garnish);
        }

        public void AddToppings(Topping topping)
        {
            _topping.Add(topping);
        }
    }
}

问题根源

  1. LoadToppings和LoadGarnishes方法仅提取了第一个<>包裹的条目,未循环处理所有配料/装饰
  2. LoadPizzas和LoadBurgers中提取配料列表时,仅获取了整个字符串,未拆分为单个配料名称
  3. 调用Load方法时,仅添加了单个对象,未处理批量添加逻辑

修复方案

1. 修改Load方法为批量返回列表

将LoadToppings改为返回List<Topping>,LoadGarnishes改为返回List<Garnish>,循环解析所有条目:

static List<Topping> LoadToppings(string toppingsLine)
{
    var toppings = new List<Topping>();
    // 提取[]内的内容
    int start = toppingsLine.IndexOf('[') + 1;
    int end = toppingsLine.IndexOf(']');
    string toppingsContent = toppingsLine.Substring(start, end - start);
    // 拆分每个<name,price>条目
    string[] toppingEntries = toppingsContent.Split(new[] { ">,<" }, StringSplitOptions.RemoveEmptyEntries);
    foreach (string entry in toppingEntries)
    {
        // 清理首尾的<>
        string cleanedEntry = entry.Trim('<', '>');
        string[] parts = cleanedEntry.Split(',');
        if (parts.Length == 2)
        {
            string name = parts[0].Trim();
            string price = parts[1].Trim();
            toppings.Add(new Topping(name, price));
        }
    }
    return toppings;
}

static List<Garnish> LoadGarnishes(string garnishesLine)
{
    var garnishes = new List<Garnish>();
    int start = garnishesLine.IndexOf('[') + 1;
    int end = garnishesLine.IndexOf(']');
    string garnishesContent = garnishesLine.Substring(start, end - start);
    string[] garnishEntries = garnishesContent.Split(new[] { ">,<" }, StringSplitOptions.RemoveEmptyEntries);
    foreach (string entry in garnishEntries)
    {
        string cleanedEntry = entry.Trim('<', '>');
        if (!string.IsNullOrEmpty(cleanedEntry))
        {
            string[] parts = cleanedEntry.Split(',');
            if (parts.Length == 2)
            {
                string name = parts[0].Trim();
                string price = parts[1].Trim();
                garnishes.Add(new Garnish(name, price));
            }
        }
    }
    return garnishes;
}

2. 修改Pizza和Burger的Load方法,拆分配料列表

调整LoadPizzas和LoadBurgers,将配料字符串拆分为单个名称:

static Pizza LoadPizzas(string pizzaLine)
{
    // 提取<>内的内容
    int start = pizzaLine.IndexOf('<') + 1;
    int end = pizzaLine.IndexOf('>');
    string pizzaContent = pizzaLine.Substring(start, end - start);
    
    // 拆分Name、Toppings、Price
    string[] pizzaParts = pizzaContent.Split(new[] { ",Toppings:", ",Price:" }, StringSplitOptions.None);
    string name = pizzaParts[0].Replace("Name:", "").Trim();
    string toppingsStr = pizzaParts[1].Trim('[', ']');
    string price = pizzaParts[2].Trim();
    
    // 拆分配料名称
    List<string> toppingNames = string.IsNullOrEmpty(toppingsStr) 
        ? new List<string>() 
        : toppingsStr.Split(',').Select(t => t.Trim()).ToList();
    
    return new Pizza(name, toppingNames, price);
}

static Burger LoadBurgers(string burgerLine)
{
    int start = burgerLine.IndexOf('<') + 1;
    int end = burgerLine.IndexOf('>');
    string burgerContent = burgerLine.Substring(start, end - start);
    
    string[] burgerParts = burgerContent.Split(new[] { ",Garnishes:", ",Price:" }, StringSplitOptions.None);
    string name = burgerParts[0].Replace("Name:", "").Trim();
    string garnishesStr = burgerParts[1].Trim('[', ']');
    string price = burgerParts[2].Trim();
    
    List<string> garnishNames = string.IsNullOrEmpty(garnishesStr) 
        ? new List<string>() 
        : garnishesStr.Split(',').Select(g => g.Trim()).ToList();
    
    return new Burger(name, garnishNames, price);
}

注:这里假设Pizza和Burger类的构造函数支持接收List<string>类型的配料参数,如果原构造函数是接收字符串,需要同步修改类定义。

3. 修改调用逻辑,批量添加对象

在switch语句中,循环添加批量返回的对象:

switch (token)
{
    case "Toppings":
        List<Topping> toppings = LoadToppings(file);
        foreach (var topping in toppings)
        {
            menu.AddToppings(topping);
        }
        break;
    case "Garnishes":
        List<Garnish> garnishes = LoadGarnishes(file);
        foreach (var garnish in garnishes)
        {
            menu.AddGarnish(garnish);
        }
        break;
    case "Pizza":
        Pizza pizza = LoadPizzas(file);
        menu.AddPizza(pizza);
        break;
    case "Burger":
        Burger burger = LoadBurgers(file);
        menu.AddBurger(burger);
        break;
}

额外注意事项

  • 确保Topping、Garnish、Pizza、Burger类的构造函数参数与修改后的Load方法返回值匹配
  • 可以添加异常处理逻辑,防止文本格式异常导致解析失败

内容的提问来源于stack exchange,提问作者Legois

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 15:44:56