2009-07-23 79 views
0

我正在處理一些相當低效的C#代碼,它們想要刪除空白行。它這樣做是:如何替換無限循環?

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

單個替換不會與應付(例如)\ n \ n \ n的輸入端,因此需要循環。我認爲它應該起作用,而且通常都是這樣。

但有時它設法進入一個無限循環,我不明白如何。在每次迭代中\ n的數量應該減少,所以它應該最終終止。

任何想法?

+2

你有一個例子行,其中它不會停止?一個調試器? – 2009-07-23 17:23:30

+0

我的回答顯示了一種情況下,這將迫使它來運行無限 – 2009-07-23 17:25:03

+0

這是我如何獲取引起無限循環討厭的字符串: \t \t \t \t就是System.IO.StreamReaderå文件= System.IO.File.OpenText(@ 「C:\ XFER \ s.tab」); \t \t \t \t string b = aFile.ReadToEnd(); \t \t \t \t aFile.Close(); 文件s.tab包含這些18十六進制字節: FF FE 41 00 0D 0A 00 0D 0A 00 0D 0A 00 42 00 這裏是從我的節目的輸出: 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 所以這是無效的unicode。但我仍然認爲它不應該發生。 – Rob625 2009-07-24 14:29:56

回答

6

將這項工作:

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

爲什麼額外\ n?我在下面發佈的答案應該只用\ n +來處理。 – 2009-07-23 17:26:44

+0

是的,這應該工作。額外\ n是提高效率所必需的。這樣,連續的換行符被雙倍和三倍(以及更多)所取代。但是單獨的一個換行符是單獨存在的。另外,通過使用這種方法,您不再需要循環。在這種情況下,正則表達式更好。 – 2009-07-23 17:29:20

+0

這是一個過早的優化,以防止正則表達式浪費匹配,以'\ n'替換'\ n'這是一個NOOP。 – notnoop 2009-07-23 17:30:34

0

你能給一個字符串此進入一個無限循環的例子嗎?此外,要調試您的程序,您可以嘗試將其替換爲:

while(b.IndexOf("\n\n")>=0) 
{ 
    Console.Write(b) 
    Console.Write(b.IndexOf("\n\n").ToString()) 
    b = b.Replace("\n\n", "\n"); 
} 

並查看它輸出的內容。

+0

不幸的是我的例子是一個13000字符的字符串。 我添加了一些Console.Writes,它們確認IndexOf在連續迭代中返回相同的值。 使用Visual Studio 2003,我看不到如何查看字符串並查看非打印字符。我想我可以添加更多的寫入。 – Rob625 2009-07-23 17:41:29

6

我沒有解釋你無法解釋的死循環(你是否確定它是無限的?你有沒有檢查過字符串是否改變?),但是用正則表達式可以更容易,更快速地完成:

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

這是最好的方法,國際海事組織。 – 2009-07-23 17:29:16

0

我只是把這個答案放在這裏來澄清一個點,以防其他人出現,並建議上面的代碼將無限循環,如果b是一個空字符串。這是不正確的:

String b = String.Empty; 

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

// output: -1 

documentation指出IndexOf將返回0,如果傳遞給它的價值參數是空的,如果不是字符串本身(在這種情況下b)是空的。

0

我已經把問題固定在一個討厭的字符串上,我通過閱讀一個文件(下面的完整代碼)。

文件s.tab包含這18個十六進制字節:FF FE 41 00 0D 0A 00 0D 0A 00 0D 0A 00 42 00

下面是我的程序輸出的調試:

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 

所以這與無效的unicode有關。我已經打印出字符串b的字符的十進制值,從i = 3 = IndexOf(「\ n \ n」)開始。 IndexOf似乎將10作爲換行符(OK),然後是2573(即0D 0A)作爲另一個(不是OK?)。然後替換不同意。

很明顯,文件中的數據有問題。但我仍然認爲這不應該發生。 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); 
     }