【问题标题】:How to get String Line number in Foreach loop from reading array?如何从读取数组中获取 Foreach 循环中的字符串行号?
【发布时间】:2010-12-12 17:10:26
【问题描述】:

该程序通过将文本文件的某些部分分组到“sections”数组中来帮助用户解析文本文件。

所以问题是“是否有任何方法可以找出数组中的行号/位置?”该程序利用一个 foreach 循环来读取“sections”数组。

有人可以就代码提供建议吗?谢谢!

namespace Testing
{
class Program
{
    static void Main(string[] args)
    {
        TextReader tr = new StreamReader(@"C:\Test\new.txt");

        String SplitBy = "----------------------------------------";

        // Skip 5 lines of the original text file
        for(var i = 0; i < 5; i++) 
        { 
            tr.ReadLine();
        }

        // Read the reststring 

        String fullLog = tr.ReadToEnd();

        String[] sections = fullLog.Split(new string[] { SplitBy }, StringSplitOptions.None);

        //String[] lines = sections.Skip(5).ToArray();

        int t = 0;

        // Tried using foreach (String r in sections.skip(4)) but skips sections instead of the Text lines found within each sections
        foreach (String r in sections)
        {
            Console.WriteLine("The times are : " + t);

            // Is there a way to know or get the "r" line number?
            Console.WriteLine(r);
            Console.WriteLine("============================================================");
            t++;
        }
    }
}
}

【问题讨论】:

  • 投反对票。这就像您之前提出的同一个愚蠢问题的第三个化身。问题本身甚至与 API 或语言无关,它与常识有关。你要么拥有它,要么没有。更重要的是,答案几乎就在您的代码中 - 您只需将 2 和 2 放在一起。

标签: c# .net arrays string file-io


【解决方案1】:

foreach 循环没有任何类型的循环计数器。您可以保留自己的计数器:

int number = 1;
foreach (var element in collection) {
  // Do something with element and number,

  number++;
}

或者,也许更简单,利用 LINQ 的 Enumerable.Select 为您提供当前索引:

var numberedElements = collection.Select((element, index) => new { element, index });

numberedElements 是具有属性elementindex 的匿名类型实例的集合。如果是文件,您可以这样做:

var numberedLines = File.ReadLines(filename)
                        .Select((Line,Number) => new { Line, Number });

优点是整个东西都是惰性处理的,所以它只会将文件的部分读入你实际使用的内存中。

【讨论】:

  • 不调用 File.ReadLines 会导致整个文件被读入内存...进入string[] 行?
  • @Mike:不,你对File.ReadAllLines的想法。 File.ReadLines 是 .NET 4 中的新功能。
  • 当一切都失败时,尝试 LINQ。然后试着回忆一下你当初为什么不使用 LINQ,哈哈。
  • @MunnkiPhD:LINQ 会不会像 XML 和暴力:如果它不工作,你使用的不够多? :-)
【解决方案2】:

据我所知,没有办法知道您在文件中的行号。您要么必须自己跟踪这些行,要么再次读取文件,直到到达该行并沿途数数。

编辑: 所以你试图在主字符串被SplitBy分割后获取数组中字符串的行号? 如果该子字符串中有特定的分隔符,您可以再次拆分它 - 虽然,这可能不会给您所需的内容,除了...

你基本上回到了第一格。

您可以尝试用换行符分割节字符串。这应该将其吐出到与字符串中的行号相对应的数组中。

【讨论】:

  • 我认为你弄错了......问题是数组中字符串的行号。
【解决方案3】:

是的,您可以使用 for 循环代替 foreach。此外,如果您知道文件不会太大,您可以将所有行读入一个数组:

string[] lines = File.ReadAllLines(@"C:\Test\new.txt");

【讨论】:

    【解决方案4】:

    好吧,不要使用 foreach,使用 for 循环

    for( int i = 0; i < sections.Length; ++ )
    {
        string section = sections[i];
        int lineNum = i + 1;
    }
    

    当然,您也可以在使用 foreach 循环时维护一个计数器,但没有理由这样做,因为您可以使用标准的 for 循环,它是为这类事情设计的。

    当然,这不会一定为您提供文本文件中字符串的行号,除非您在 Environment.NewLine 上进行拆分。您正在拆分大量“-”字符,我不知道您的文件的结构。您最终可能会低估行号,因为所有“---”位都将被丢弃。

    【讨论】:

      【解决方案5】:

      不像你的代码那样写。您必须自己跟踪行号。你的代码有问题的地方:

      1. 您在代码开头跳过了 5 行,您必须对此进行跟踪。
      2. 使用Split 方法,您可能会从原始行集合中“删除”行。你必须找出来知道你做了多少分割,因为它们是行数的原始部分。

      我建议不要采用您现有的方法,而是在访问文件每一行的经典索引 for 循环中进行解析和搜索。这可能意味着放弃Split 之类的便利,而是使用例如手动在文件中查找标记。 IndexOf.

      【讨论】:

        【解决方案6】:

        昨天看完所有答案后,我有了一个更简单的问题解决方案。

        由于字符串每行后都有一个换行符,因此可以将字符串拆分并转换为新数组,然后可以根据数组位置找出行号。

        密码:

        foreach (String r in sections) { Console.WriteLine("The times are : " + t); IList<String> names = r.Split('\n').ToList<String>(); }

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-07-03
          • 2010-12-13
          • 2017-11-08
          • 2016-06-18
          • 1970-01-01
          • 2021-09-06
          • 2015-05-03
          相关资源
          最近更新 更多