在列表对象中查找制表符时出错

本文关键字:制表符 出错 查找 列表 对象 | 更新日期: 2024-10-30 06:45:47

我正在使用C#,winforms应用程序。

我正在读取一个文本文件,其中每行都有按制表符划分的字段:

我将每一行放在名为 tic_string 的列表中。从这里开始,我尝试搜索每个列表对象,找到选项卡,并将每个字段放在自己的数组中。所以会有一个数组用于column acolumn bcolumn c...等。

问题是当我尝试在列表对象中查找选项卡时,它什么也找不到。 这是我的代码:

string[] tic_num = new string[row_counter];
string[] tic_title = new string[row_counter];
string[] tic_owner = new string[row_counter];
string[] tic_open_date = new string[row_counter];
int last_tab = 0;
int char_counter = 0;
int feild_counter = 1;
int feild_char_count = 1;
int current_row=0;
string temp_feild = "";
char temp_char;
char tab_char = ''t';
foreach (string tic_string_value in tic_string)
{
    temp_char = tic_string_value[char_counter];
    if (temp_char == tab_char)
    {
        Console.WriteLine("tab_found");
        if (feild_char_count == 1)
        {
            temp_feild = "";
        }
        else
        {
            temp_feild = tic_string_value.Substring(last_tab, feild_char_count);
        }
        last_tab = char_counter;
        feild_char_count = 0;
        switch (feild_counter)
        {
            case 1:
                tic_num[current_row] = temp_feild;
                break;
            case 2:
                tic_title[current_row] = temp_feild;
                break;
            case 3:
                tic_owner[current_row] = temp_feild;
                break;
            case 4:
                tic_open_date[current_row] = temp_feild;
                break;
        }
    }
    current_row++;
    feild_char_count++;
    char_counter++;
    if (feild_counter == 5)
        feild_counter = 1;
}

在列表对象中查找制表符时出错

对于如此简单的任务来说,您的代码似乎太复杂了。不要逐个字符解析每一行字符,只需使用String.Split等辅助函数:

foreach (string tic_string_value in tic_string)
{
    var parts = tic_string_value.Split(new [] { ''t' }, 
                                       StringSplitOptions.RemoveEmptyEntries);
    tic_num[current_row] = parts[0];
    tic_title[current_row] = parts[1];
    tic_owner[current_row] = parts[2];
    tic_open_date[current_row] = parts[3];
    current_row++;
}

首先,我从您的代码风格推断您可能熟悉 C/C++并且不熟悉 C#,因为这段代码具有特别"C++"的味道。它让我想起了我第一次自己跳转时自己的 C# 代码。

我很高兴您描述了您试图解决的问题,而不是简单地发布代码并询问在哪里可以找到错误,因为我认为您实际上可以更轻松地解决问题。

考虑以下代码(这假设您正在迭代此代码之外的每一行,并且我省略了您已经指定的一些变量声明):

int field_counter = 0;
foreach (var field in tic_string.Split(''t')) {
    switch (field_counter++) {
        case 0:
            tic_num[current_row] = field;
            break;
        case 1:
            tic_title[current_row] = field;
            break;
        case 2:
            tic_owner[current_row] = field;
            break;
        case 3:
            tic_open_date[current_row] = field;
            break;
    }
}

这利用了 C# 的简洁性并删除了相当多的代码行,这总是好的。String.Split 方法将为您处理大部分字符串拆分,因此无需手动完成所有操作并跟踪字符。

注意:我保留了某些字段名称的原始命名,尽管通常最好在 C# 代码中使用 CamelCase。

现在我从您的原始代码中注意到,您的数据中可能没有实际意义上的"行"(即由换行符拆分),而是您可能将数据完全分隔为制表符,并使用每行有固定数量的列来拆分行。

如果是这种情况,我是否可以建议以下代码块可以帮助您:

int i = 0;
        foreach (var group in tic_string.GroupBy(x => i++ % 4)) {
            int current_row = 0;
            foreach (var field in group) {
                switch (group.Key) {
                    case 0:
                        tic_num[current_row] = field;
                        break;
                    case 1:
                        tic_title[current_row] = field;
                        break;
                    case 2:
                        tic_owner[current_row] = field;
                        break;
                    case 3:
                        tic_open_date[current_row] = field;
                        break;
                }
                current_row++;
            }
        }

当然,现在您可能需要使这些块适应您的代码,而不是逐字使用它。我希望他们至少表现出对这个问题的不同思考方式。特别是,学习使用各种 LINQ 扩展方法和 LINQ 查询也将非常有帮助 - 它们是使 C# 代码如此快速且易于开发的一部分。

祝您好运解决您的问题!

您也可以使用列表而不是 4 个字符串数组:

    public class ObjectToBeUsed
{
    public Person(int num, string title, string owner, string opendate)
    {
        this.Num = num;
        this.Title = title;
        this.Owner = owner;
        this.OpenDate = opendate;
    }
    private int _num;
    public int Num
    {
        get { return _num; }
        set { _num = value; }
    }

    private string _title;
    public string Title
    {
        get { return _title; }
        set { _title = value; }
    }
    private string _owner;
    public string Owner
    {
        get { return _owner; }
        set { _owner = value; }
    }
    private string _opendate;
    public string OpenDate
    {
        get { return _opendate; }
        set { _opendate = value; }
    }
}

这是描述文本文件中每一行的类。

            System.IO.StreamReader file = new System.IO.StreamReader("test.txt");
        string currentLine = null;
        List<ObjectToBeUsed> peopleList = new List<ObjectToBeUsed>();
        while ((currentLine = file.ReadLine()) != null)
        {
            string[] tokens = Regex.Split(currentLine, @"'t");
            peopleList.Add(new ObjectToBeUsed(Convert.ToInt32(tokens[0]), tokens[1], tokens[2], tokens[3]));
        }

代码非常不言自明,但如果您需要任何进一步的解释,请继续。