【问题标题】:Deleting a Record in a CSV file using C#使用 C# 删除 CSV 文件中的记录
【发布时间】:2021-09-08 11:54:34
【问题描述】:

我正在使用 C# 中的 WPF 开发一个基本应用程序,它读取存储在 CSV 文件中的数据。我已经能够在我的应用程序的其他部分成功读取数据并使用 WPF 中的数据网格显示它们。我现在希望在用户输入搜索词时删除记录。然后应用程序将使用流读取器读取 CSV 文件并查找记录与用户输入的搜索词匹配的位置,然后删除记录。

我当前的删除功能代码如下:

private void DeleteCategory(object sender, RoutedEventArgs e)
        {
            ////take user input for animal category
            string category = inputCategoryDelete.Text;

            var lines = new List<string>();

            using (StreamReader reader = new StreamReader(@"C:\Users\ashle\OneDrive\Documents\Object Orientated Programming\Practise\CSV Files\animalcategory.csv"))
            {
                while (!reader.EndOfStream)
                {
                    for (int i = 0; i < lines.Count; i++)
                    {
                        if (lines[i].StartsWith(category))
                        {
                            lines.RemoveAt(i);
                            break;
                        }
                        else
                        {
                            continue;
                        }
                    }
                }
            }

                //close the popup
                addCategoryPopup.IsOpen = false;

        }

我目前发现自己陷入了 for 循环,因为它永远无法进入 if 和 else。在查看 i 和 lines.count 的值时。我发现 i 每次都可以增加 1,但 lines.count 始终为 0。我试图在一些基本调试中放置一些断点。当我将 for 循环更改为 for(int i = 0; i

如果有人能够看到我做错了什么,那就太好了。我是新来的,所以如果我遗漏了任何内容或没有正确解释任何内容,请提出任何问题:)

【问题讨论】:

  • "但 lines.count 始终为 0" - 因为 lines 是一个空列表。它已声明但从未使用过。您希望lines 包含哪些信息?为什么?
  • @David 抱歉,我希望行列表包含我的 csv 文件中的记录,因此实际上会包含一些信息。
  • 您需要将数据放入列表中,然后计数将非零
  • 考虑使用一个库来读取CSV,比如NReco.Csv
  • 你因为while (!reader.EndOfStream)而陷入循环,阅读器还没有被使用所以它永远不会在EndOfStream

标签: c# csv


【解决方案1】:

未经测试,但在我看来应该可以工作:

        ////take user input for animal category
        string category = "asd"; //getting cathegory that needs to be deleted
        int columnIndex = 1; //index of the field that contains the cathegories
        char separatorChar = '\t'; //separator char is tabulator that separates the different columns

        var lines = new List<string[]>(); //csv so it has multiple columns

        using (StreamReader reader = new StreamReader(@"file path")) //getting the file
        {
            while (!reader.EndOfStream)
            {
                lines.Add(reader.ReadLine().Split(separatorChar)); //adding the files content line-by-line and split by the separator character
            }
        }
        //now we have the lines list that contains the csv-s lines and splitted into string entities that represents the column of a line

        foreach (var line in lines) //we iterate through the line entities
        {
            if (line[columnIndex] == category) //cathegory equals with the user inputted cathegory?
                line[columnIndex] = string.Empty; //delete column content if this is true
        }


        using (var writer= new StreamWriter(@"file path")) //write back to the file
        {
            foreach (var item in lines)
            {
                writer.WriteLine(string.Join(separatorChar.ToString(), item)); //convert string[] to string (line)
            }
        }

一个简单的修改是你只想替换特定列中的数据,所以我修改了代码来处理这个问题并写了一个回写。

【讨论】:

  • 也非常感谢您的代码中的 cmets。这真的帮助我了解我哪里出错了
【解决方案2】:

考虑如下所示。 (这样您就可以构建一个不以您的类别开头的文件行列表,因为这样可以节省您检查然后从列表中删除它的时间。)

    using (StreamReader reader = new StreamReader(@"C:\Users\ashle\OneDrive\Documents\Object Orientated Programming\Practise\CSV Files\animalcategory.csv"))
    {
        while ( reader.Peek() >=0)
        {
            var line = reader.ReadLine();
            if(!line.StartsWith(category))
                lines.Add(line);
        }
    }

【讨论】:

    猜你喜欢
    • 2014-01-04
    • 1970-01-01
    • 2019-03-09
    • 1970-01-01
    • 1970-01-01
    • 2020-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多