0

皆さん、プログラムに読み込んでいるtxtファイルから不要な行をスキップするのに苦労しています。データの形式は次のとおりです。

Line 1
Line 2
Line 3
Line 4

Line 5
Line 6
Line 7
Line 8

1 行目を読み、3 行目と 4 行目を削除し、空白を削除してから、5 行目を読み、7 行目と 8 行目を削除したいと考えています。テキストファイルの行。これは私がこれまでに試したことです:

         string TextLine;


        System.IO.StreamReader file =
           new System.IO.StreamReader("C://log.txt");
        while ((TextLine = file.ReadLine()) != null)
        {

            foreach (var i in Enumerable.Range(2, 3)) file.ReadLine();
            Console.WriteLine(TextLine);


        }

ご覧のとおり、範囲については、開始を 2 行目として指定し、空白を含む 3 行をスキップしています。ただし、 Enumerable.Range の最初のパラメーターは重要ではないようです。0 を入れても同じ結果が得られます。私が今持っているように、プログラムは .Range 関数の 2 番目のパラメーターで指定された数まで、最初の行からトリミングします。この問題を回避する方法を知っている人はいますか? ありがとう

4

6 に答える 6

3

すべての行を配列に読み込んでから、必要な行にインデックスを付けてみませんか

var lines = File.ReadAllLines("C://log.txt");
Console.WriteLine(lines[0]);
Console.WriteLine(lines[5]);

繰り返しセクションが一貫している非常に大きなファイルの場合は、readメソッドを作成して次の操作を実行できます。

while (!file.EndOfStream)
{
    yield return file.ReadLine();
    yield return file.ReadLine();
    file.ReadLine();
    file.ReadLine();
    file.ReadLine();
}

または、必要なブロック形式についても同様です。

于 2012-04-16T15:30:51.900 に答える
2

私はあなたが2つの場所(1つはループ内にあり、次に再びループ内にある)で行を読みたいとは思わない。私はこのアプローチを取ります:

while ((TextLine = file.ReadLine()) != null)
{
    if (string.IsNullOrWhitespace(TextLine)) // Or any other conditions
        continue;

    Console.WriteLine(TextLine);
} 
于 2012-04-16T15:31:21.793 に答える
2

もちろん、範囲は問題ではありません...あなたがしていることは、whileループの反復ごとに一度に2行をスキップすることです-2-3はファイルリーダーポインターには影響しません。どの行にいるのかを示すカウンターを用意し、行番号がスキップしたいものの1つである場合はスキップすることをお勧めします。

int currentLine = 1;
while ((TextLine = file.ReadLine()) != null)
{           
    if ( LineEnabled( currentLine )){
        Console.WriteLine(TextLine);
    }

    currentLine++;
}

 private boolean LineEnabled( int lineNumber )
 {
     if ( lineNumber == 2 || lineNumber == 3 || lineNumber == 4 ){ return false; }
     return true;
 }
于 2012-04-16T15:27:57.740 に答える
2

これは、OP の要求に応じてここで提供されるソリューションの拡張バージョンです。

public static IEnumerable<string> getMeaningfulLines(string filename)
{
  System.IO.StreamReader file =
    new System.IO.StreamReader(filename);
    while (!file.EndOfStream)
    {
      //keep two lines that we care about
      yield return file.ReadLine();
      yield return file.ReadLine();
      //discard three lines that we don't need
      file.ReadLine();
      file.ReadLine();
      file.ReadLine();
    }
}

public static void Main()
{
  foreach(string line in getMeaningfulLines(@"C:/log.txt"))
  {
    //or do whatever else you want with the "meaningful" lines.
    Console.WriteLine(line);
  }
}

入力ファイルが突然終了した場合に壊れにくくなる別のバージョンを次に示します。

//Just get all lines from a file as an IEnumerable; handy helper method in general.
public static IEnumerable<string> GetAllLines(string filename)
{
  System.IO.StreamReader file =
    new System.IO.StreamReader(filename);
  while (!file.EndOfStream)
  {
    yield return file.ReadLine();
  }
}

public static IEnumerable<string> getMeaningfulLines2(string filename)
{
  int counter = 0;
  //This will yield when counter is 0 or 1, and not when it's 2, 3, or 4.
  //The result is yield two, skip 3, repeat.
  foreach(string line in GetAllLines(filename))
  {
    if(counter < 2)
      yield return line;

    //add one to the counter and have it wrap, 
    //so it is always between 0 and 4 (inclusive).
    counter = (counter + 1) % 5;
  }
}
于 2012-04-16T19:15:34.773 に答える
0

このようなことを試しましたか?

using (var file = new StreamReader("C://log.txt"))
{
    var lineCt = 0;
    while (var line = file.ReadLine())
    {
        lineCt++;

        //logic for lines to keep
        if (lineCt == 1 || lineCt == 5)
        {
            Console.WriteLine(line);
        }
    }
}

ただし、これが非常に固定された形式の入力ファイルでない限り、固定の行番号ではなく、各行をどう処理するかを理解するための別の方法を見つけるでしょう。

于 2012-04-16T15:29:51.663 に答える
0

状態のドキュメントEnumerable.Range:

public static IEnumerable<int> Range(
int start,
int count
)

Parameters

start
 Type: System.Int32
 The value of the first integer in the sequence.

count
 Type: System.Int32
 The number of sequential integers to generate.

したがって、最初のパラメーターを変更しても、プログラムのロジックは変更されません。

ただし、これは奇妙な方法です。ループはforはるかに単純で、理解しやすく、はるかに効率的です。

また、現在のコードは最初の行を読み取り、3 行をスキップしてから最初の行を出力してから繰り返します。

于 2012-04-16T15:28:52.093 に答える