C# 如何替换无限循环?
我正在编写一些效率相当低的C#代码,希望删除空白行。它是这样做的: string b; ... while ( b.IndexOf("\n\n") >= 0 ) b = b.Replace ("\n\n", "\n"); b串; ... 而(b.IndexOf(“\n\n”)>=0) b=b.替换(“\n\n”和“\n”); 单个替换无法处理(例如)输入中的\n\n\n,因此需要循环。我认为它应该起作用,而且通常是这样 但有时它会设法进入一个无限循环,我不明白怎么做。在每次迭代中\n的数量应该减少,因此它最终应该终止 有什么想法吗?这行得通吗:C# 如何替换无限循环?,c#,string,replace,infinite-loop,C#,String,Replace,Infinite Loop,我正在编写一些效率相当低的C#代码,希望删除空白行。它是这样做的: string b; ... while ( b.IndexOf("\n\n") >= 0 ) b = b.Replace ("\n\n", "\n"); b串; ... 而(b.IndexOf(“\n\n”)>=0) b=b.替换(“\n\n”和“\n”); 单个替换无法处理(例如)输入中的\n\n\n,因此需要循环。我认为它应该起作用,而且通常是这样 但有时它会设法
String c = Regex.Replace(b, "\n\n+", "\n");
你能给出一个字符串的例子吗?它会进入一个无限循环?此外,要调试您的程序,您可以尝试将其替换为:
while(b.IndexOf("\n\n")>=0)
{
Console.Write(b)
Console.Write(b.IndexOf("\n\n").ToString())
b = b.Replace("\n\n", "\n");
}
查看它的输出。我无法解释您无法解释的无限循环(您确定它是无限的吗?是否检查了字符串是否更改?),但使用正则表达式可以更轻松、更快地完成此操作:
b = System.Text.RegularExpressions.Regex.Replace(b, "\n+", "\n")
我把这个答案放在这里是为了澄清一点,以防其他人出现,并建议如果b是空字符串,上面的代码将无限循环。这是不正确的:
String b = String.Empty;
Console.WriteLine(b.IndexOf("\n\n"));
// output: -1
如果传递给它的value参数为空,则
IndexOf
将返回0,而不是如果字符串本身(在本例中为b)为空。我已将问题归结为通过读取文件获得的讨厌字符串(下面是完整代码)
文件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?)。那你就不同意了
显然,文件中的数据有问题。但我仍然认为这不应该发生。索引of和Replace应该一致
我正在实施MSAED的解决方案。非常感谢
调试代码:
{
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);
}
你有没有一个不停的例子?有没有闯入过调试器?我的回答显示了一个会迫使它无限运行的情况。这里是我如何得到一个导致无限循环的讨厌字符串:System.IO.StreamReader aFile=System.IO.File.OpenText(@“c:\xfer\s.tab”);字符串b=aFile.ReadToEnd();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。。。完成n=1,i=3,b=A??B所以这与无效的unicode有关。但我仍然认为不应该发生。为什么要额外\n?我在下面发布的答案只需\n+即可解决。是的,这应该有效。额外的\n是提高效率所必需的。这样,双和三(或更多)连续换行将被替换。但是一个单线馈送是单独存在的。此外,通过使用此方法,您不再需要循环。在这种情况下,正则表达式就更好了。用“\n”替换“\n”是一种不合时宜的做法,这是一种过早的优化,以防止正则表达式浪费匹配。我完全同意您的看法。我正要写完全相同的代码,但你比我快。所以我们现在有了一个公认的答案,但仍然没有解释最初问题的原因…这是最好的方法,依我看。不幸的是,我的示例是一个13000字符的字符串。我添加了一些Console.Writes,确认IndexOf在连续迭代中返回相同的值。使用VisualStudio2003,我看不到如何查看字符串和非打印字符。我想我可以多加些笔迹。