在不使用更多内存的情况下循环遍历多行字符串的每一行的好方法是什么(例如,不将其拆分为数组)?
答案 0 :(得分:135)
我建议使用StringReader
和LineReader
类的组合,这是[{3}}的一部分,但也可以在MiscUtil中使用 - 您可以轻松地将该类复制到你自己的实用工程。你会这样使用它:
string text = @"First line
second line
third line";
foreach (string line in new LineReader(() => new StringReader(text)))
{
Console.WriteLine(line);
}
循环遍历字符串数据体中的所有行(无论是文件还是其他)是如此常见,以至于它不应该要求调用代码来测试null等:)尽管如此,如果你 想要手动循环,这是我通常比Fredrik更喜欢的形式:
using (StringReader reader = new StringReader(input))
{
string line;
while ((line = reader.ReadLine()) != null)
{
// Do something with the line
}
}
这样你只需要测试一次null值,你也不必考虑do / while循环(由于某种原因,它总是比直接循环占用我更多的努力)。
答案 1 :(得分:69)
您可以使用StringReader
一次读取一行:
using (StringReader reader = new StringReader(input))
{
string line = string.Empty;
do
{
line = reader.ReadLine();
if (line != null)
{
// do something with the line
}
} while (line != null);
}
答案 2 :(得分:7)
string textReaderText = "TextReader is the abstract base " +
"class of StreamReader and StringReader, which read " +
"characters from streams and strings, respectively.\n\n" +
"Create an instance of TextReader to open a text file " +
"for reading a specified range of characters, or to " +
"create a reader based on an existing stream.\n\n" +
"You can also use an instance of TextReader to read " +
"text from a custom backing store using the same " +
"APIs you would use for a string or a stream.\n\n";
Console.WriteLine("Original text:\n\n{0}", textReaderText);
// From textReaderText, create a continuous paragraph
// with two spaces between each sentence.
string aLine, aParagraph = null;
StringReader strReader = new StringReader(textReaderText);
while(true)
{
aLine = strReader.ReadLine();
if(aLine != null)
{
aParagraph = aParagraph + aLine + " ";
}
else
{
aParagraph = aParagraph + "\n";
break;
}
}
Console.WriteLine("Modified text:\n\n{0}", aParagraph);
答案 3 :(得分:3)
我知道这已经得到了解答,但我想补充一下我自己的答案:
using (var reader = new StringReader(multiLineString))
{
for (string line = reader.ReadLine(); line != null; line = reader.ReadLine())
{
// Do something with the line
}
}
答案 4 :(得分:1)
这是一个快速的代码片段,它将在字符串中找到第一个非空行:
string line1;
while (
((line1 = sr.ReadLine()) != null) &&
((line1 = line1.Trim()).Length == 0)
)
{ /* Do nothing - just trying to find first non-empty line*/ }
if(line1 == null){ /* Error - no non-empty lines in string */ }
答案 5 :(得分:1)
尝试使用String.Split方法:
string text = @"First line
second line
third line";
foreach (string line in text.Split('\n'))
{
// do something
}
答案 6 :(得分:0)
要更新.NET 4的这一古老问题,现在有一种更整洁的方法:
var lines = File.ReadAllLines(filename);
foreach (string line in lines)
{
Console.WriteLine(line);
}
答案 7 :(得分:0)
有时候,我认为我们可以使解决方案过于复杂,以避免重复一行代码。这就是我首先关注此问题的原因。
经过一番思考,我得出的结论是,最简单的解决方案是在循环之前和循环内部重复ReadLine
。
using (var stringReader = new StringReader(input))
{
var line = await stringReader.ReadLineAsync();
while (line != null)
{
// do something
line = await stringReader.ReadLineAsync();
}
}
我意识到这可能不符合DRY原则,但鉴于简单性,我认为值得考虑。