Как уже отмечали другие, вы звоните Substring
с неправильными значениями. Требуется начальная позиция и длина (и вы переходите в конечную позицию).
Однако другой способ решения этой проблемы может состоять в том, чтобы написать метод, который генерирует для вас знак с определенным текстом и определенной шириной, и затем вы можете просто вызывать этот метод столько раз, сколько захотите, чтобы создать равный знаки.
Если мы напишем метод, который принимает строку и ширину, мы можем соответственно сгенерировать знак. Однако один вопрос, который возникает быстро, заключается в том, что нам делать, если длина строки превышает ширину? Я думаю, что есть два варианта:
- Обрезать строку до ширины
- Разверните знак, чтобы соответствовать строке
Итак, я добавил параметр expandWidth
, который при значении true расширяет знак для размещения самой длинной строки. Если установлено значение false, строка будет обрезана.
Остальная часть метода не требует пояснений: разбить входную строку на символы новой строки, если в знаке должно быть более одной строки, определить самую длинную строку, которую нам нужно отобразить, и настроить ширину знака, если expandWidth
is true
, запишите нашу строку заголовка (верхняя часть знака), используйте Substring
, PadLeft
и PadRight
, чтобы центрировать каждую строку в ширину, и, наконец, напишите наш нижний колонтитул (нижнюю часть знака ):
public static void WriteSign(string signText, int signWidth = 10, bool expandWidth = true)
{
// Split input into lines, in case there's
// more than one line to display on the sign
var lines = signText
.Split(new[] {'\r', '\n'}, StringSplitOptions.None)
.Select(line => line.Trim());
// Determine the sign width based on the longest line
var actualSignWidth = expandWidth
? Math.Max(lines.Max(l => l.Length), signWidth)
: signWidth;
// Write header
Console.WriteLine("╔" + new string('═', Math.Max(0, actualSignWidth)) + "╗");
// Write lines
foreach (var line in lines)
{
var signLine = line.Substring(0, Math.Min(line.Length, actualSignWidth))
.PadLeft(Math.Min(actualSignWidth, (actualSignWidth + line.Length) / 2))
.PadRight(actualSignWidth);
Console.WriteLine("║" + signLine + "║");
}
// Write footer
Console.WriteLine("╚" + new string('═', Math.Max(0, actualSignWidth)) + "╝");
}
Теперь мы можем создать строку с \n
символами между каждой группой слов, и мы можем отобразить их все по одному знаку или разделить их и отобразить несколько отдельных знаков.
Например:
private static void Main(string[] cmdArgs)
{
var signText = "If our road signs\nCatch your eye\nSmile\nBut don't forget\nTo buy\nBurma shave";
var splitText = signText.Split('\n');
var signWidth = splitText.Max(line => line.Length) + 2;
// Write a sign with all the lines on one sign
WriteSign(signText, signWidth);
// Write a divider to separate the first sign from the rest
Console.WriteLine(new string('-', Console.WindowWidth));
// Write a separate sign for each line
foreach (var line in splitText) WriteSign(line, signWidth);
GetKeyFromUser("\nDone! Press any key to exit...");
}
выход