2017-10-09 2 views
2

Je souhaite diviser une chaîne sans utiliser la méthode String.Split.
J'ai trouvé une solution possible here. Le code que j'utilise provient de la deuxième réponse.
Ceci est mon code:La division d'une chaîne sans utiliser la méthode String.Split ne renvoie pas le résultat correct

public string[] SplitString(string input, char delimiter) 
{ 
    List<String> parts = new List<String>(); 
    StringBuilder buff = new StringBuilder(); 

    for (int i = 0; i < input.Length; i++) 
    { 
     if (input[i] == delimiter) 
     { 
      parts.Add(buff.ToString()); 
      buff.Clear(); 
     } 
     else 
     { 
      buff.Append(input[i]); 
     } 
    } 
    return parts.ToArray(); 
} 

Mon problème est que lorsque je tente de diviser une chaîne comme celui-ci
chien personne voiture chat par « », le résultat contient les mots sans la dernière un (dans cet exemple - personne).
Si après le dernier mot il y a un espace blanc, le résultat est correct.

J'ai essayé d'ajouter quelque chose comme i == input.Length lorsque la boucle est 0-i < = input.Length. Mais le résultat était toujours sans le dernier mot.
Ai-je raté quelque chose?

+2

Vous devez vérifier si le tampon n'est pas vide à la fin de la boucle for. S'il est vide, c'est fait, ou il reste encore un dernier jeu de caractères – praty

+1

Après la boucle, vérifiez la longueur du tampon. Si c'est plus de 0, ajoutez-le à la liste. –

Répondre

4

Ajouter un autre parts.Add(buff.ToString()); après avoir quitté la boucle - pour vider le dernier mot dans la collection. Vous pouvez vérifier la longueur avant de le faire ou non comme commenté et expliqué pourquoi par @hvd.

if(buff.Length != 0) 
{ 
    parts.Add(buff.ToString()); 
} 
return parts.ToArray(); 

Une autre approche, au lieu d'utiliser un StringBuilder serait:

public static string[] SplitString(string input, char delimiter) 
{ 
    List<String> parts = new List<String>(); 
    int start = 0; 
    for(int i = 0; i < input.Length; i++) 
    { 
     if(input[i] == delimiter) 
     { 
      parts.Add(input.Substring(start, i - start)); 
      start = i + 1; 
     } 
    } 
    parts.Add(input.Substring(start, input.Length - start)); 
    return parts.ToArray(); 
} 

Ou utilisez yield return et retour IEnumerable<string>:

public static IEnumerable<string> SplitString(string input, char delimiter) 
{ 
    int start = 0; 
    for(int i = 0; i < input.Length; i++) 
    { 
     if(input[i] == delimiter) 
     { 
      yield return input.Substring(start, i - start); 
      start = i + 1; 
     } 
    } 
    yield return input.Substring(start, input.Length - start); 
} 
+2

"Avant cela, assurez-vous que le tampon n'est pas vide" - Non, ne le vérifiez pas. L'OP obtient des chaînes vides dans les résultats s'il y a des espaces de début ou des espaces intérieurs consécutifs, à des fins de cohérence, l'OP devrait également obtenir des chaînes vides s'il y a des espaces de fin. – hvd

0

Voici ce qui vous manque dans votre code après pour la boucle:

for (int i = 0; i < input.Length; i++) 
    { 
     if (input[i] == delimiter) 
     { 
      parts.Add(buff.ToString()); 
      buff.Clear(); 
     } 
     else 
     { 
      buff.Append(input[i]); 
     } 
    } 

    // This you need to add 
    if (!string.IsNullOrEmpty(buff.ToString())) 
    { 
     parts.Add(buff.ToString()); 
    } 

    return parts.ToArray();