Немного грубое решение может выглядеть так:
private static string CutOff(string input, int length)
{
if ( length <= 0 ) throw new ArgumentOutOfRangeException(nameof(length));
if (length >= input.Length) return input; //whole input
var index = length - 1;
if (char.IsWhiteSpace(input[index])) return input.Substring(0, length); //just cut off
if (length < input.Length - 1 && !char.IsWhiteSpace(input[length]))
{
//word continues, search for whitespace character to the left
while (length >= 0 && !char.IsWhiteSpace(input[length]))
{
length--;
}
if ( length < 0)
{
//single long word
return "Can't cut off without breaking word";
}
}
//cut off by length
return input.Substring(0, length);
}
Он обрабатывает все случаи - если строка слишком короткая, она возвращает все. Если индекс обрезки падает на символ пробела, мы обычно его обрезаем. Если это продолжается, мы ищем ближайший пробел слева. Если мы не найдем ничего, мы не сможем безопасно вырезать, так как ввод - одно длинное слово.
Для более простого решения вы можете разбить ввод по пробелам, а затем продолжать добавлять слова, пока они соответствуют требуемой длине. Однако мое первое решение более эффективно, поскольку не требует дополнительной памяти и не требует чтения всей строки.
private static string SplitCut( string input, int length)
{
var words = input.Split(" ");
StringBuilder builder = new StringBuilder();
foreach (var word in words)
{
if ( builder.Length + word.Length <= length)
{
builder.Append(word);
}
else
{
//can't add more
break;
}
}
if (builder.Length == 0)
return "Can't cut off without breaking word";
return builder.ToString();
}