web-dev-qa-db-fra.com

C #: Boucle entre les lignes d'une chaîne multiligne

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

77
flamey

Je suggère d'utiliser une combinaison de StringReader et de ma classe LineReader, qui fait partie de MiscUtil mais également disponible dans cette réponse StackOverflow - vous pouvez facilement copier cette classe dans votre propre projet d'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);
}

Boucler sur toutes les lignes d'un corps de données de chaîne (qu'il s'agisse d'un fichier ou autre) est si courant qu'il ne devrait pas être nécessaire que le code appelant teste null, etc. :) Ceci dit, si vous faites veux 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 n'avez qu'à tester la nullité une fois, et vous n'avez pas non plus à penser à une boucle do/while (ce qui, pour une raison quelconque, me prend toujours plus de temps à lire qu'une boucle while).

132
Jon Skeet

Vous pouvez utiliser une StringReader pour 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);
}
66
Fredrik Mörk

à partir de 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);
6
tster

Je sais que cela a été répondu, mais je voudrais 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
    }
}
2
Niels

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

Pour mettre à jour cette ancienne question pour .NET 4, il existe maintenant une méthode beaucoup plus simple: 

var lines = File.ReadAllLines(filename);

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