【问题标题】:Cutting a string at specified lengths以指定长度切割字符串
【发布时间】:2015-03-03 05:21:35
【问题描述】:

我有一个包含字符串的数组,我想知道如何获取一个字符串并在指定的像素长度处切下一部分并将其添加到数组中。

例如,

string[] string1 = { "Hello World" };

我正在使用 XNA,所以我可以通过使用来获取像素长度,

FontName.MeasureString(string1[0]).Length()

例如,如果上面的代码返回 100 像素长,我如何将字符串剪切为 70 像素长并将其添加回数组以获得此:

string1 = { "Hello Wo", "rld" } // Hello Wo(100px), rld(30px)

我已经研究过使用 StringBuilder,但它以字符长度测量字符串。如果没有可能的方法来实现这一点,是否有一种方法可以找出字符串的开头和我希望字符串在哪里截断的像素点之间有多少个字符,那么我会能够使用 StringBuilder。

编辑:

所以我尝试循环遍历数组,然后循环遍历数组中的每个字符并将其添加到列表中,它有点工作,但在将它添加回数组后我无法让它继续。

string[] stringArray = { "Hello World" };
List<Char> charList = new List<Char>();
List<Char> charList2 = new List<Char>();
List<String> stringList = new List<String>();


        for (int i = 0; i < stringArray.Length; i++)
        {
            if ((int)consolas.MeasureString(stringArray[i]).Length() > 30)
            {
                for (int c = 0; c < stringArray[i].Length; c++)
                {
                    if (consolas.MeasureString(string.Join("", charList)).Length() < 30)
                    {
                        charList.Add(stringArray[i][c]);
                    }
                    else
                    {
                        charList2.Add(stringArray[i][c]);
                    }
                }
            }
        }

        stringList.Add(string.Join("", charList));
        stringList.Add(string.Join("", charList2));
        stringArray = stringList.ToArray();
        charList.Clear();
        charList2.Clear();
        stringList.Clear();

上面的代码返回给我

stringArray = { "He", "llo World" };

这是我想要的,但我希望它继续这样做

stringArray = { "He", "ll", "o World" };

当字符串超过 30px 时继续拆分字符串。我已经考虑过了,我似乎不明白为什么它没有进一步分裂。

【问题讨论】:

  • 设置一个循环...为数组的下一部分保留一个字符串,并向其中添加字符,直到测量字符串产生您想要的像素长度,然后将该字符串的副本添加到数组的末端,并清除它以冲洗并重复。
  • 我没有使用过 XNA。我(可能很天真)的做法是进行二进制搜索 - 取一半字符串并检查其像素长度 - 如果太长,则取前半部分的一半并检查;如果太短,就拿下半场的一半来检查一下。
  • 你的第一个需要是字符串数组吗?你是否曾经要处理例如? string[] stringArray = { "Hello World", "More Hello World" };

标签: c# arrays string xna


【解决方案1】:

我做了一个逻辑模型,使用字符串长度的替代检查,而不是像素长度。应该很清楚如何在 Measure 函数中替换它。

(替换的一个限制是我没有测试过 x 太短但 x+1 太长的情况。所以请测试一下!)

我对性能不做任何声明。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] stringArray = { "333", "Hello World", "A", "World gone mad and society has, too" };
            List<string> newStrings = new List<string> ();

            foreach (string currentString in stringArray)
            {
                bool finished = false;
                int start = 0;
                int end = 0;
                while (!finished)
                {

                    if (currentString.Length == end)
                    {
                        finished = true;
                        newStrings.Add(currentString.Substring(start, end - start));
                    }
                    else if (Measure(currentString.Substring(start, end - start)) == 0)
                    {
                        newStrings.Add(currentString.Substring(start, end - start));

                        start = end;
                    }
                    else if (Measure(currentString.Substring(start, end-start)) < 0)
                    {
                        end++;
                    }
                    else //adding one more made it too long
                    {
                        end--;
                        newStrings.Add(currentString.Substring(start, end - start));
                        start = end;
                    }
                }
            }

            foreach (string s in newStrings)
            {
                Console.WriteLine(s);
            }

            Console.ReadLine();

        }



        private static int Measure(string s)
        {
            //you would check using something like 
            //int length = ((int)consolas.MeasureString(stringArray[i]).Length()); 
            //int requiredValue = 30;
            //but I have substituted just plain string.Length to show the logic

            int length = s.Length;
            int requiredValue = 3;

            if (length == requiredValue) return 0;
            if (length < requiredValue) return -1;

            return 1;
        }
    }
}

【讨论】:

  • 如果您的第一个字符超过 30 像素,它也会陷入无限循环。所以,呃,不要那样做? :P
  • 谢谢您,我一定会检查一下,如果我有任何问题,请回来。
【解决方案2】:

在 MSDN 上找到了这个。看起来对你有用;

private void MeasureStringMin(PaintEventArgs e)
{

    // Set up string. 
    string measureString = "Measure String";
    Font stringFont = new Font("Arial", 16);

    // Measure string.
    SizeF stringSize = new SizeF();
    stringSize = e.Graphics.MeasureString(measureString, stringFont);

    // Draw rectangle representing size of string.
    e.Graphics.DrawRectangle(new Pen(Color.Red, 1), 0.0F, 0.0F, stringSize.Width, stringSize.Height);

    // Draw string to screen.
    e.Graphics.DrawString(measureString, stringFont, Brushes.Black, new PointF(0, 0));
}

方法页面:https://msdn.microsoft.com/en-us/library/system.drawing.graphics.measurestring(v=vs.110).aspx

【讨论】:

  • 我认为这与我的问题无关,我正在使用 XNA,所以我已经可以测量字符串并将字符串绘制到屏幕上,但是如果我不使用 XNA,它会是可用于测量和绘制琴弦。我遇到的主要问题是将字符串拆分为一定长度并将分割的段添加到数组中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-10
  • 2013-11-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多