我在C#工作,winforms应用程序。
我正在阅读一个文本文件,其中每一行都有以制表符分隔的字段:
我将每行放在名为tic_string
的列表中。从这里我试图搜索每个列表对象,找到选项卡,并将每个字段放在自己的数组中。因此,column a
,column b
,column 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;
}
答案 0 :(得分:2)
对于这样简单的任务,您的代码似乎太复杂了。不要用char解析每一行char,只需使用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++;
}
答案 1 :(得分:1)
首先,我从你的代码风格中推断出你可能熟悉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#代码如此快速和易于开发的一部分。
祝你解决问题!
答案 2 :(得分:0)
您也可以使用列表而不是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]));
}
代码非常明显,但如果您需要进一步解释,请继续。