Jaki jest dobry sposób na zapętlenie każdego wiersza wielowierszowego ciągu bez używania większej ilości pamięci (na przykład bez dzielenia go na tablicę)?
Jaki jest dobry sposób na zapętlenie każdego wiersza wielowierszowego ciągu bez używania większej ilości pamięci (na przykład bez dzielenia go na tablicę)?
Odpowiedzi:
Sugeruję użycie kombinacji StringReader
i moja LineReader
klasa, która jest częścią MiscUtil, ale jest również dostępna w tej odpowiedzi StackOverflow - możesz łatwo skopiować tylko tę klasę do własnego projektu narzędziowego. Używałbyś tego w ten sposób:
string text = @"First line
second line
third line";
foreach (string line in new LineReader(() => new StringReader(text)))
{
Console.WriteLine(line);
}
Zapętlenie nad wszystkie linie w ciele danych String (czy to jest plik lub cokolwiek) jest tak powszechne, że nie powinno wymagać kod wzywający do testowania dla wartości null itp :) Mimo, że jeśli nie chce zrobić pętla ręczna, jest to forma, którą zazwyczaj wolę od Fredrika:
using (StringReader reader = new StringReader(input))
{
string line;
while ((line = reader.ReadLine()) != null)
{
// Do something with the line
}
}
W ten sposób wystarczy raz przetestować pod kątem nieważności i nie trzeba też myśleć o pętli do / while (która z jakiegoś powodu zawsze wymaga więcej wysiłku niż przeczytanie prostej pętli while).
Możesz użyć a, StringReader
aby odczytać wiersz na raz:
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);
}
z MSDN dla StringReader
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);
Oto krótki fragment kodu, który znajdzie pierwszą niepustą linię w ciągu:
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 */ }
Spróbuj użyć metody String.Split:
string text = @"First line
second line
third line";
foreach (string line in text.Split('\n'))
{
// do something
}