2009-07-23 16 views
0

私は、空白行を削除したい、かなり非効率的なC#コードに取り組んでいます。どのように無限ループを置き換えることができますか?

 
      string b; 
... 
      while (b.IndexOf("\n\n") >= 0) 
       b = b.Replace ("\n\n", "\n"); 

入力に1つの置換が(たとえば)\ n \ n \ nに対応しないため、ループが必要です。私はそれが働くべきだと思います、そして、それは通常行います。

しかし、それは無限ループに陥ることがありますが、私はどのように理解できません。すべての反復で、\ nの数は減らされるはずなので、最終的に終了する必要があります。

アイデア?

+2

あなたはそれが停止しない例ラインを持っていますか?デバッガで壊れたことはありますか?@ \t \t \t \tはSystem.IO.StreamReader aFileの位置= System.IO.File.OpenText(: –

+0

私の答えはここに無限に –

+0

を実行するために、これを強制する一つのケースは、私は無限ループの原因となる厄介な文字列を取得する方法であることを示しています"c:\ xfer \ s.tab"); \t \t \t \t文字列b = aFile.ReadToEnd(); \t \t \t \t aFile.Close();ここで FF FE 41 00 0D 0A 00 0D 0A 00 0D 0A 00 42 00 私のプログラムから出力された: ファイルs.tabは、これらの18進バイトを含む てb.length = 8 ループはn = 1、 i = 3、b = A? ?? B i = 3、b(i)= 10 2573 3328 ... done n = 1、i = 3、b = A? ?? B 無効なユニコードとは関係があります。しかし、私はまだそれが起こるとは思わない。 – Rob625

答えて

6

うこの作品:

String c = Regex.Replace(b, "\n\n+", "\n"); 
+0

なぜ余分な\ n?私が下に投稿した答えはちょうど\ n +でそれを世話するべきです。 –

+0

はい、これはうまくいくはずです。効率を上げるには余分な\ nが必要です。そうすれば、二重三連以上の改行が置き換えられます。しかし、1つの改行は残されています。また、このメソッドを使用すると、もはやループは必要ありません。この場合、正規表現は単純に優れています。 –

+0

Regexの無駄な照合が '\ n'をNOOPである '\ n'に置き換えないようにするのは時期尚早の最適化です。 – notnoop

0

あなたは、これが無限ループに入っているため、文字列の例を与えることができますか?また、プログラムをデバッグする場合は、次のように置き換えてみてください。

出力内容を確認してください。

+0

残念ながら私の例は13000文字列です。 私は、IndexOfが連続した繰り返しで同じ値を返すことを確認するConsole.Writesをいくつか追加しました。 Visual Studio 2003を使用すると、文字列を調べて印刷できない文字を表示する方法がわかりません。私はもっ​​と書くことができると思います。 – Rob625

6

説明できない無限ループについては説明がありません(文字列が変更されているかどうか確認しましたか?)が、正規表現ではこれをはるかに簡単かつ迅速に行うことができます:

b = System.Text.RegularExpressions.Regex.Replace(b, "\n+", "\n") 
+0

これは最高のアプローチ、IMOです。 –

0

他の誰かが来た場合に、この点を明確にするために、この回答をここに載せて、bが空文字列の場合、上に掲載されたコードが無限ループすることを示唆しています。それは正しくありません。それに渡された値パラメータが空の場合、IndexOfは、文字列自体(この場合b)が空でない場合は、0を返すこと

String b = String.Empty; 

Console.WriteLine(b.IndexOf("\n\n")); 

// output: -1 

documentation状態。

0

私はファイルを読むことによって(以下の完全なコード)、厄介な文字列に問題を固定しました。ここではFF FE 00 0D 0A 00 42 00

41 00 0D 0A 00 0D 0Aは私のプログラムのデバッグ出力です:

だから、
b.Length=8 loop n=1, i=3, b=A?? 
?? B 
stuck at i=3, b(i)=10 2573 3328... 
done n=1, i=3, b=A?? 
?? B 

ファイルs.tabは、これらの18進のバイトが含まれていますそれは無効なユニコードと関係しています。私は文字列bの文字の小数点を、i = 3 = IndexOf( "\ n \ n")で始まります。 IndexOfは10を改行(OK)と見なし、2573(0D 0A)を別のもの(OKではない)と見なします。次に、Replaceは同意しません。

明らかにファイル内のデータに問題があります。しかし、私はまだこれが起こるとは思わない。 IndexOfとReplaceは同意する必要があります。

私はmsaeedのソリューションを実装しています。どうもありがとう。

デバッグコード:

 { 
      System.IO.StreamReader aFile = System.IO.File.OpenText(@"c:\xfer\s.tab"); 
      string a = aFile.ReadToEnd(); 
      aFile.Close(); 

      int nn=0, ii; 
      Console.WriteLine ("a.Length={0}", a.Length); 
      while ((ii=a.IndexOf("\n\n")) >= 0) 
      { 
       nn++; 
       Console.WriteLine("loop n={0}, i={1}, a={2}" 
        , nn 
        , ii 
        , a); 
       if (ii == a.IndexOf("\n\n")) 
       { 
        Console.WriteLine ("stuck at i={0}, a(i)={1} {2} {3}..." 
         , ii 
         , (int)(a.ToCharArray()[ii]) 
         , (int)(a.ToCharArray()[ii+1]) 
         , (int)(a.ToCharArray()[ii+2]) 
         ); 
        break; 
       } 
       a = a.Replace ("\n\n", "\n"); 
      } 
      Console.WriteLine("done n={0}, i={1}, a={2}", nn, ii, a); 
     } 
関連する問題