0

我想使用/and拆分从 txt 文件中读取的文本*

但是,我浏览文件并'Index was outside the bounds of the array.'出现!

任何帮助,将不胜感激

OpenFileDialog ofd = new OpenFileDialog();
if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{

    string fileToOpen = ofd.FileName;

    System.IO.StreamReader sr = new System.IO.StreamReader(fileToOpen);
    string fileContent = sr.ReadLine();
    string[] items = fileContent.Split('*').ToArray<string>();
    string[] buffer;

    foreach (string s in items)
    {
        ListViewItem lv = new ListViewItem();
        buffer = s.Split('/').ToArray<string>();
        lv.Text = items[0].ToString();
        lv.SubItems.Add(items[1].ToString());
        lv.SubItems.Add(items[2].ToString());
        lv.SubItems.Add(items[3].ToString());
        listView1.Items.Add(lv);
        lv.Text = buffer[0];

        lv.SubItems.Add(buffer[1]);
        lv.SubItems.Add(buffer[2]);
        listView1.Items.Add(lv);
    }
}

是我的代码,谢谢!

4

4 回答 4

2

在 foreach 循环中,您将再次使用'/'as拆分字符串

 buffer = s.Split('/').ToArray<string>();

如果'/'在上面的字符串(s)中没有找到,你的缓冲区可能没有2/3项目,所以

lv.SubItems.Add(buffer[1]);
lv.SubItems.Add(buffer[2]);

以上行可能导致索引超出范围错误。

或者可能是由于:

lv.SubItems.Add(items[1].ToString());
lv.SubItems.Add(items[2].ToString());
lv.SubItems.Add(items[3].ToString());

数组索引应始终小于数组中的长度(或项数)。

您可以同时使用两者来拆分'/'字符串'*'

fileContent.Split(new [] {"*", "/"}, StringSplitOptions.None).ToArray<string>();
于 2013-10-25T17:44:02.097 回答
2

使用 items.Count 来确定 items 数组中存在多少元素。并使用从 0 开始到小于 items.Count 的索引。

即代码应该是这样的:

foreach (string s in items)
{
    ListViewItem lv = new ListViewItem();
    buffer = s.Split('/').ToArray<string>();
    lv.Text = items[0].ToString();
    for(int i=0; i<items.Count; i++)
    {
       lv.SubItems.Add(items[i].ToString());
    }
    listView1.Items.Add(lv);
    lv.Text = buffer[0];

    lv.SubItems.Add(buffer[1]);
    lv.SubItems.Add(buffer[2]);
    listView1.Items.Add(lv);
}
于 2013-10-25T18:12:41.463 回答
0

为避免索引超出范围,请以 linq 方式重构代码以处理数据的动态特性,并且不再索引。此外,通过使用正则表达式来解析数据可能是有益的情况。

这是使用正则表达式和 Linq 以及在将子项添加到列表视图时删除大部分索引的过程的近似值。此外,从正则表达式模式中提取的数据使用命名匹配组并且没有索引。

总体概念是使用 foreach 而不是 for;本身。

列表视图示例

string data = "*Alpha/Beta/Gamma*Zebra/Delta/Tango";

string pattern = @"\*((?<SlashValues>[^/*]+)/?)+";

Regex.Matches(data, pattern, RegexOptions.IgnorePatternWhitespace)
     .OfType<Match>()
     .Select (mt => new {
                        LVI = new ListViewItem(),

                        SubItems = mt.Groups["SlashValues"].Captures
                                                           .OfType<Capture>()
                                                           .Select (cp => cp.Value),
                        }
            )
    .ToList()
    .ForEach(item => {
                        item.LVI.Text = item.SubItems.FirstOrDefault(),
                        LVI.AddRange(item.SubItems.Skip(1));
                        listView1.Items.Add(item);
                     });

正则表达式示例

取出 ListViewItem 代码可以更好地理解正则表达式处理。每个匹配项都是一个新的 ListView 项,其中模式将 * 作为锚点。找到之后,它最终会查找除以 / 或 * 的多个值,因为它表示匹配的结束和新匹配的开始。

试试这是作为控制台应用程序:

string data = "*Alpha/Beta/Gamma*Zebra/Delta/Tango";

// Put into group "SlashValues" into its capture collection
// [] is a set 
// [^] ^ in the set means NOT
// [^*/] Not a * or /
// [^*/]+ + means one or more 
//       which gets all characters up to a / or *
string pattern = @"\*((?<SlashValues>[^/*]+)/?)+";

Regex.Matches(data, pattern, RegexOptions.IgnorePatternWhitespace)
     .OfType<Match>()
     .Select (mt => mt.Groups["SlashValues"].Captures
                                            .OfType<Capture>()
                                            .Select (cp => cp.Value))
     .ToList()
     .ForEach(rs => Console.WriteLine (string.Join(", ", rs)));

/*
Alpha, Beta, Gamma
Zebra, Delta, Tango
*/
于 2013-10-25T18:51:22.060 回答
0

您的代码对数组索引大小做出了不安全的假设!

您应该添加一些if条件来获得保护,IndexOutOfRangeException或者改为使用循环。

例如,你怎么知道这里有 4 个元素:

    lv.Text = items[0].ToString();
    lv.SubItems.Add(items[1].ToString());
    lv.SubItems.Add(items[2].ToString());
    lv.SubItems.Add(items[3].ToString());

这样做是为了安全起见:

for(int i = 0; i < items.Length; i++)
{
  lv.SubItems.Add(items[i])
}

或者至少先检查您是否有 4 个元素

if(items.Length == 4)
{
 lv.Text = items[0].ToString();
 lv.SubItems.Add(items[1].ToString());
 lv.SubItems.Add(items[2].ToString());
 lv.SubItems.Add(items[3].ToString());
}
于 2013-10-25T17:48:58.650 回答