C #: boucle à travers des lignes de chaîne multiligne

100

Quel est le bon moyen de parcourir chaque ligne d'une chaîne multiligne sans utiliser beaucoup plus de mémoire (par exemple sans la diviser en un tableau)?

flamboyant
la source

Réponses:

158

Je suggère d'utiliser une combinaison de StringReaderet ma LineReaderclasse, qui fait partie de MiscUtil mais également disponible dans cette réponse StackOverflow - vous pouvez facilement copier uniquement cette classe dans votre propre projet utilitaire. Vous l'utiliseriez comme ceci:

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

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

Bouclez toutes les lignes dans un ensemble de données de chaîne (que ce soit un fichier ou autre) est si commun qu'il ne devrait pas exiger que le code appelant à tester pour null etc :) Cela dit, si vous ne voulez faire une boucle manuelle, c'est la forme que je préfère généralement à celle de Fredrik:

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

De cette façon, vous ne devez tester la nullité qu'une seule fois, et vous n'avez pas non plus à penser à une boucle do / while (ce qui, pour une raison quelconque, me demande toujours plus d'efforts à lire qu'une boucle while directe).

Jon Skeet
la source
74

Vous pouvez utiliser a StringReaderpour lire une ligne à la fois:

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
la source
1
Génial; +1; cela a aidé; mais je veux juste ajouter que l'on n'a pas réellement besoin d'utiliser le bloc "using" car il n'y a pas de ressources à fermer dans ce cas. Voir les remarques dans l'article StringReader sur docs.microsoft.com
RD Alkire
10

Je sais que cela a été répondu, mais j'aimerais ajouter ma propre réponse:

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

depuis MSDN pour 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
la source
2

Voici un extrait de code rapide qui trouvera la première ligne non vide d'une chaîne:

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
la source
2

Pour mettre à jour cette ancienne question pour .NET 4, il existe maintenant un moyen beaucoup plus soigné:

var lines = File.ReadAllLines(filename);

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

Essayez d'utiliser la méthode String.Split:

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

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