【问题标题】:C# Read and split from .txt to struct arrayC# 从 .txt 读取并拆分为结构数组
【发布时间】:2020-04-07 08:23:51
【问题描述】:

我正在尝试为我的控制台应用程序进行基本登录。我将用户数据存储在 .txt 文件中,如下所示: ID;Name;IsAdmin。 txt 有几行。

在应用程序中,我想将用户数据存储在 struct User 数组中。我似乎找不到读取文件、拆分并将不同数据放在正确位置的方法。这是我目前所拥有的:

加载用户数据到结构数组

public static void LoadIDs()
        {
            int entries = FileHandling.CountRows(usersPath);
            User[] users = new User[entries]; //Length depends on how many lines are in the .txt

            for (int i = 0; i < users.Length; i++)
            {
                users[i] = new User(1,"a",false); //ID(int), name, isAdmin [This is where I want to put the data from the .txt]
            }
        }

阅读和分割文本

public static string ReadFileToArray(string path)
        {
            String input = File.ReadAllText(path);

            foreach (var record in input.Split('\n'))
            {
                foreach (var data in record.Split(';'))
                {
                    return data;
                }
            }

            return null;
        }

我知道这根本行不通,但我的知识还很有限,我想不出其他解决方案。

【问题讨论】:

  • 您必须逐行读取文件并为每一行创建一个User 实例
  • 使用 File.ReadAllLines 代替 ReadAllText
  • 想想你的ReadFileToArray 正在做什么......你按行拆分,然后按; 拆分每一行,然后你只返回第一件事......你为什么要想这样做吗?
  • 如果你想让它保持基本状态,那就太复杂了。跳过文件一起读取,只将数据存储在内存中。
  • 使用File.ReadLines 而不是File.ReadAllLines

标签: c# arrays file text struct


【解决方案1】:

您有一个更好的工具来存储您的用户。您可以使用 List 代替数组(这会迫使您知道加载的数据的长度),您可以在其中添加元素,同时阅读它们。

另一个需要改变的地方是 File.ReadLines 中的 File.ReadAllText。这将允许直接在循环中逐行读取文件

public List<User> BuildUserList(string path)
{
    List<User> result = new List<User>();
    foreach (var record in File.ReadLines(path)
    {
        string[] data = record.Split(';'))
        User current = new User();
        current.ID = Convert.ToInt32(data[0]);
        current.Name = data[1];
        current.IsAdmin = Convert.ToBoolean(data[2]);
        result.Add(current);
    }
    return result;
}

现在,如果需要,您可以像使用数组一样使用列表

List<User> users = BuildUserList("yourfile.txt");
if(users.Count > 0)
{
    Console.WriteLine("Name=" + users[0].Name);
}    

【讨论】:

    【解决方案2】:

    如果我假设你的文件尤其是每一行都有Id;Name;Admin 值,我会写下类似下面的内容来提取它。请注意,那里有简单的语法,但以下逻辑将有助于初学者了解如何实现这一点。

                List<User> userList = new List<User>();
    
                // Read the file located at c:\test.txt (this might be different in your case)
                System.IO.StreamReader file = new System.IO.StreamReader(@"c:\test.txt");
                string line;
                while ((line = file.ReadLine()) != null)
                {
                    //following logic will read each line and split by the separator before
                    // creating a new User instance. Remember to add more defensive logic to
                    // cover all cases
                    var extract = line.Split(';');
                   userList.Add(new User()
                   {
                       Id = extract[0],
                       Name = extract[1],
                       IsAdmin = extract[2]
                   });
                }
    
                file.Close();
    
                //at this stage you will have List of User and converting it to array using following call
    
                var userArray = userList.ToArray();
    

    【讨论】:

      【解决方案3】:

      作为另一种变体,linq 解决方案可能如下所示:

          var users = (
              from string line in System.IO.File.ReadAllLines(@"..filepath..")
              let parts = line.Split(';')
              where parts.Length == 3
              select new User() {
                  ID = Convert.ToInt32(parts[0]),
                  Name = parts[1],
                  IsAdmin = Convert.ToBoolean(parts[2])}
                  ).ToArray();
      

      这可以优雅而简短,错误处理可能有点困难。

      【讨论】:

        【解决方案4】:

        这将延迟读取您的文件,因此它可以轻松处理非常大的文件(假设您的其余代码可以):

        public IEnumerable<User> ReadUsers(string path)
        {
          return File.ReadLines(path)
            .Select(l=>l.Split(';'))
            .Select(l=> new User
            {
              Id = int.Parse(l[0]),
              Name = l[1],
              IsAdmin = bool.Parse(l[2])
            });
        }
        

        public IEnumerable<User> ReadUsers(string path)
        {
          return File.ReadLines(path)
            .Select(l=>l.Split(';'))
            .Select(l=> new User(int.Parse(l[0]), l[1], bool.Parse(l[2])));
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-04-30
          • 1970-01-01
          • 1970-01-01
          • 2016-08-19
          • 1970-01-01
          • 2016-08-01
          • 2013-06-03
          • 2022-01-05
          相关资源
          最近更新 更多