遍历添加到StringBuilder的字符串

4
我有以下代码:

StringBuilder sb = new StringBuilder();
sb.Append("Ola");
sb.Append("Jola");
sb.Append("Zosia");

我能否使用 forforeach 遍历 StringBuilder 对象?

我能否显示其中一个元素?例如,Console.WriteLine(sb[0]); 不起作用。


2
听起来 StringBuilder 不是你应该使用的正确对象,你想要做什么? - Sayse
4
这似乎是一个典型的 XY 问题,其中 X 是您的原始问题,您认为的解决方案是“我知道,我会使用StringBuilder”,导致您现在遇到问题 Y:“但现在我无法从StringBuilder中获取单独的字符串”。请解释一下您的原始问题 X。 - CodeCaster
一种可能性是将每个Append与分隔符<space>(可以是)一起存储,并使用Split(separator)进行拆分,然后显示元素数组的elements[0] - NeverHopeless
@NeverHopeless 不要这样,简单地接受你的问题所使用的数据结构是错误的。不要去实现那样的hack。 - CodeCaster
1
@CodeCaster,这真的取决于OP想要实现什么?代码可能会出错,但这取决于允许的输入字符串。我们不能在不了解细节的情况下做出决定。您建议使用List<>选项,但也许OP想坚持使用StringBuilder而没有理由。一个人有权提供可能对他人有缺陷的替代方案。 - NeverHopeless
显示剩余2条评论
6个回答

4
您似乎正在寻找一个List<string>,您可以向其中添加字符串(Add()),以便稍后可以通过索引(list[n])获取字符串并进行迭代(foreach (string s in list))。

StringBuilder不支持这样做,因为它在内部连接所有输入,并且不能区分不同Append()调用的值。

如果要从字符串列表中获取连接的字符串,请参见将列表项附加到StringBuilder


2

StringBuilder没有实现IEnumerable接口,因此无法使用foreach遍历它,但您可以像这样操作:

StringBuilder sb = new StringBuilder();
sb.Append("Ola");
sb.Append("Jola");
sb.Append("Zosia");

for (int i = 0; i < sb.Length; i++)
{
    char c = sb[i];
    if (Char.IsUpper(c)) Console.Write('\n');
    Console.Write(c);
}

1
如果 (Char.IsUpper(c)) Console.Write('\n'); 不,不行。这假定输入总是以大写字符开头,且不包含任何其他大写字符。OP 应该使用不同的数据结构或者至少正确地解释他们的问题。 - CodeCaster
@CodeCaster 我明白,但是这里的OP总是添加以大写字母开头的名称,所以只有在OP坚持要遍历一个StringBuilder的情况下才能正常工作。 - w.b

1
StringBuilder不是集合或数组,它只是一个提供了一些额外功能来处理字符串的类。它没有实现IEnumerable接口。
sb.Append方法只是像你输入"text " + "some other text"一样连接字符串,但从效率上讲更好。事实上,每个"s1" + "s2"都会创建一个新的字符串。如果你想这样做1000次,那么就会一遍又一遍地创建新的字符串,并进行很多额外的操作。StringBuilder提供了一种避免这种情况的方法,当它“渲染”字符串时,它更新相同的字符串,而不是每次都创建新的实例。

0
如果你真的想坚持使用 StringBuilder,你可以使用扩展方法来给你一个 List,然后你可以通过元素编号访问它。
internal static class ExtensionMethods
{
    public static List<string> ToList(this StringBuilder stringBuilder)
    {
        return stringBuilder.ToString().Split(new string[] { Environment.NewLine }, StringSplitOptions.None).ToList();
    }
}

您可以通过调用 ToList() 方法来访问它。
int i = 0;
StringBuilder SB = new StringBuilder();
while (i++ != 1000000)
{
    SB.AppendLine(i.ToString());
}

string ChosenElement = SB.ToList()[1000];

假设输入字符串中不包含换行符。使用 StringBuilder 构建字符串,使用 List<T> 存储您想要按索引查找和迭代的项目。 - CodeCaster
@CodeCaster 是的,它确实可以,但在最初不使用列表的情况下,这是最接近的方法。 - CathalMF

0

我知道回答这个问题已经太晚了,但我希望其他人能从中获得帮助。

 public static void Main(string[] args)
    {

        StringBuilder sb = new StringBuilder("1");
        for(int i=2; i<= 300; i++){
                sb.Append(i+" this is test.~");
        }
        foreach(string s in sb.ToString().Split('~')){
        Console.WriteLine(s);
        }
    }

编辑: 在你的例子中:

 StringBuilder sb = new StringBuilder();
     sb.Append("Ola~");
     sb.Append("Jola~");  
     sb.Append("Zosia~");

 //foreach loop ver sb object

  foreach(string s in sb.ToString().Split('~')){
         Console.WriteLine(s);
          }

现在还不晚,只需编写一个说明即可。 - Derek Brown
我只是在字符串末尾添加了一个特殊字符 **~**,然后使用 'sb.append();' 将字符串拆分成该字符。您可以添加自己的标记,然后在 foreach 循环中使用该标记拆分 StringBuilder 对象。 - user9223210

0

我能够通过使用这篇文章作为指南,为一个非常相似的场景得到一个可行的解决方案:

在C#中替换字符串中的换行符

如果您能够使用sb.AppendLine,那么您可以通过换行字符'\r'和'\n'分割结果ToString()的字符串。

// e.g whereas you had:
StringBuilder sb = new StringBuilder();
sb.Append("Ola");
sb.Append("Jola");
sb.Append("Zosia");

// the scenario will only work if you did the following:
StringBuilder sb = new StringBuilder();
sb.AppendLine("Ola");
sb.AppendLine("Jola");
sb.AppendLine("Zosia");

// you can split your strings as follows:
string[] resultLines = TestResultStr.ToString().Split(new char[] { '\n', '\r' });

for (int i = 0; i < resultLines.Length; i++)
{
    Console.WriteLine(resultLines[i]);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接