C #: Perulangan melalui garis-garis string multiline

100

Apa cara yang baik untuk mengulang setiap baris dari string multiline tanpa menggunakan lebih banyak memori (misalnya tanpa membaginya menjadi sebuah array)?

berapi-api
sumber

Jawaban:

158

Saya sarankan menggunakan kombinasi StringReaderdan LineReaderkelas saya , yang merupakan bagian dari MiscUtil tetapi juga tersedia dalam jawaban StackOverflow ini - Anda dapat dengan mudah menyalin hanya kelas itu ke dalam proyek utilitas Anda sendiri. Anda akan menggunakannya seperti ini:

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

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

Perulangan atas semua baris dalam tubuh data string (apakah itu file atau apa pun) begitu umum bahwa itu seharusnya tidak memerlukan kode panggilan untuk menguji for dll :) Karena itu, jika Anda tidak ingin melakukan loop manual, ini adalah bentuk yang biasanya saya sukai daripada Fredrik:

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

Dengan cara ini Anda hanya perlu menguji nullity sekali, dan Anda juga tidak perlu memikirkan loop do / while (yang karena alasan tertentu selalu membutuhkan lebih banyak usaha untuk membaca daripada loop sementara).

Jon Skeet
sumber
74

Anda dapat menggunakan a StringReaderuntuk membaca baris dalam satu waktu:

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
sumber
1
Bagus; +1; ini membantu; tetapi saya hanya ingin menambahkan bahwa seseorang sebenarnya tidak perlu menggunakan blok "menggunakan" karena tidak ada sumber daya untuk ditutup dalam kasus ini. Lihat komentar di artikel StringReader di docs.microsoft.com
RD Alkire
10

Saya tahu ini telah dijawab, tetapi saya ingin menambahkan jawaban saya sendiri:

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

dari MSDN untuk 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
sumber
2

Berikut cuplikan kode cepat yang akan menemukan baris tidak kosong pertama dalam sebuah string:

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
sumber
2

Untuk memperbarui pertanyaan kuno ini untuk .NET 4, sekarang ada cara yang jauh lebih rapi:

var lines = File.ReadAllLines(filename);

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

Coba gunakan Metode String.Split:

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

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