C #: Durchlaufen von Zeilen mit mehrzeiligen Zeichenfolgen

100

Was ist ein guter Weg, um jede Zeile eines mehrzeiligen Strings zu durchlaufen, ohne viel mehr Speicher zu verwenden (zum Beispiel ohne ihn in ein Array aufzuteilen)?

flammend
quelle

Antworten:

158

Ich schlage vor, eine Kombination aus StringReaderund meiner LineReaderKlasse zu verwenden, die Teil von MiscUtil ist, aber auch in dieser StackOverflow-Antwort verfügbar ist. Sie können einfach nur diese Klasse in Ihr eigenes Hilfsprojekt kopieren. Sie würden es so verwenden:

string text = @"First line
second line
third line";

foreach (string line in new LineReader(() => new StringReader(text)))
{
    Console.WriteLine(line);
}

Looping über alle Linien in einem Körper von String - Daten (ob , dass eine Datei ist oder was auch immer) sind so verbreitet , dass es nicht den Aufruf Code erfordern sollte die Prüfung auf null etc werden :) das gesagt zu haben, wenn Sie sich eine tun wollen manuelle Schleife, dies ist die Form, die ich normalerweise gegenüber Fredriks bevorzuge:

using (StringReader reader = new StringReader(input))
{
    string line;
    while ((line = reader.ReadLine()) != null)
    {
        // Do something with the line
    }
}

Auf diese Weise müssen Sie nur einmal auf Nichtigkeit testen und müssen auch nicht an eine do / while-Schleife denken (was aus irgendeinem Grund immer mehr Aufwand beim Lesen erfordert als eine gerade while-Schleife).

Jon Skeet
quelle
74

Sie können a verwenden StringReader, um jeweils eine Zeile zu lesen:

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);
}
Fredrik Mörk
quelle
1
Toll; +1; das half; aber ich möchte nur hinzufügen, dass man den "using" -Block nicht wirklich verwenden muss, da in diesem Fall keine Ressourcen zum Schließen vorhanden sind. Siehe Anmerkungen im StringReader-Artikel unter docs.microsoft.com
RD Alkire,
10

Ich weiß, dass dies beantwortet wurde, aber ich möchte meine eigene Antwort hinzufügen:

using (var reader = new StringReader(multiLineString))
{
    for (string line = reader.ReadLine(); line != null; line = reader.ReadLine())
    {
        // Do something with the line
    }
}
Niels
quelle
7

von MSDN für 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);
tster
quelle
2

Hier ist ein kurzer Codeausschnitt, der die erste nicht leere Zeile in einer Zeichenfolge findet:

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 */ }
palswim
quelle
2

Um diese alte Frage für .NET 4 zu aktualisieren, gibt es jetzt einen viel besseren Weg:

var lines = File.ReadAllLines(filename);

foreach (string line in lines)
{
    Console.WriteLine(line);
}
NickG
quelle
0

Versuchen Sie es mit der String.Split-Methode:

string text = @"First line
second line
third line";

foreach (string line in text.Split('\n'))
{
    // do something
}
emmediemme82
quelle