将文本文件解析为对象的实例

问题描述 投票:0回答:1

我目前正在做一项大学作业,在将文本文件解析为对象实例时遇到问题。我正在开发的程序的简单解释是外卖店装载机。人员输入具有设定格式的文本文件,然后将其解析为对象的实例,以创建一个简单的外卖店,供用户订购和编辑其订单。以下是如何格式化文本文件以与代码一起使用的示例:

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>

这里的代码读取每一行代码,从本质上删除不必要的符号和单词,并将其放入各自的类中。我的代码实际上可以解析文本文件,但它只对第一部分进行解析。例如,奶酪和价格会被解析,但不会解析其余的配料。

namespace JustNom.Logic
{
    //The file reader menu that created a menu in which it opens and filters a specific file. 
    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();
            }
        }
    }
}
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);
        }
    }
}

这个类包含所有包含所有解析对象的对象。很抱歉冗长的描述,我正在尝试添加尽可能多的描述,因为这个项目中有很多代码。如果您想看其他课程以帮助您更多地理解我的问题,请告诉我!

我尝试循环 Load() 方法,但这并没有真正起作用。

c# object text-files
1个回答
0
投票

看看你提到的第一个问题,你已经编写了

LoadToppings
方法来仅处理第一个配料。我将在这里举一个例子来说明解决此问题的一种方法。

我修改了

LoadToppings
的返回值以返回
List<Topping>
而不是单个配料,这样我们就可以一次处理所有配料。

首先,我们可以抓取

[
]
字符之间的字符串,其中包含所有顶部对(名称和价格)。

接下来,我们可以在

<
>
字符上拆分该字符串,因此我们最终得到一个字符串列表,每个字符串仅包含内部对的配料名称和价格。

然后我们可以用逗号分割每个,并使用它们创建一个

Topping
,我们将其添加到
List<Toppings>
,并在最后返回:

List<Topping> LoadToppings(string input)
{
    var toppings = new List<Topping>();
    if (input == null) return toppings;

    if (input.Contains("["))
    {
        int start = input.IndexOf("[") + 1;
        int end = input.IndexOf("]", start);

        if (start < end)
        {
            var toppingStrings = input.Substring(start, end - start);

            // Now split on "<>" to get the individual topping
            // items, like: "cheese,80", "pepperoni,120", etc.
            var toppingPairs = toppingStrings.Split(new[] { '<', '>' }, 
                StringSplitOptions.RemoveEmptyEntries);

            foreach(var toppingPair in toppingPairs)
            {
                var parts = toppingPair.Split(',', 
                    StringSplitOptions.RemoveEmptyEntries);

                if (parts.Length == 0) continue;

                Topping topping = new Topping { Name = parts[0] };

                if (parts.Length > 1 && decimal.TryParse(parts[1], out decimal price))
                {
                    topping.Price = price;
                }

                toppings.Add(topping);
            }
        }
    }

    return toppings;     
}
© www.soinside.com 2019 - 2024. All rights reserved.