StartIndex не може бути меншим за нуль. - Помилка при спробі змінити рядок

У мене є такий код C #:

ArticleContent = ds1.Tables[0].Rows[i]["ArticleContent"].ToString();

if (ArticleContent.Length > 260)
{
   ArticleContent = ArticleContent.Remove(ArticleContent.IndexOf('.', 250)) + "...";
}

Проблема полягає в тому, що я отримую це повідомлення про помилку:

StartIndex не може бути меншим за нуль.

Чому і як це можна виправити?

9
Підказка: якщо в рядку ArticleContent немає . ?
додано Автор marc_s, джерело
Краще шукати існуючу функцію, яка робить те, що ви намагаєтеся зробити. Як ви можете собі уявити, ви не перший, хто його пише.
додано Автор hakre, джерело

7 Відповіді

Ви отримуєте цю помилку, тому що символ '. не відображається в індексі 250 або після нього, тому IndexOf повертає -1 . Потім спробуйте видалити символ у позиції -1 , який дає вам помилку, яку ви бачите.

Також розумійте, що Remove видаляє лише один символ у цій позиції , а не все після цієї позиції . Я хочу підозрювати :

if (ArticleContent.Length > 260)
{
   int lastPeriod = ArticleContent.LastIndexOf('.');
   if(lastPeriod < 0)
      lastPeriod = 257; //just replace the last three characters
   ArticleContent = ArticleContent.Substring(0,lastPeriod) + "...";
}

Це додасть еліпсів до рядка, переконавшись, що це не більше, ніж 260 символів і, якщо це можливо, порушуючи речення.

18
додано
Ні ... це означає, що немає "." ПІСЛЯ 250.
додано Автор It'sNotALie., джерело
Зрозумів дякую!
додано Автор Nave Tseva, джерело

Зрозуміло, чому це не вдається, але що саме ви намагаєтеся зробити? Якщо це просто обрізати рядок до певної довжини і вказуючи на укорочення, я можу запропонувати метод розширення, перерахований нижче. Це просто:

ArticleContent = ArticleContent.Truncate(250);

Метод скорочення:

public static string Truncate(this string pThis, int pLength)
{
    if (string.IsNullOrEmpty(pThis))
        return pThis;

    if (0 >= pLength)
        return string.Empty;

    var lTruncatedString = pThis;
    const string lEllipses = @"…";

    if (pThis.Length > pLength)
    {
        var lSubstringLength = Math.Max(pLength - lEllipses.Length, 0);
        lTruncatedString = pThis.Substring(0, lSubstringLength) + lEllipses;
        if (lTruncatedString.Length > pLength)
            lTruncatedString = lTruncatedString.Substring(0, pLength);
    }

    return lTruncatedString;
}

Я сподіваюся, що це допоможе.

3
додано
Ласкаво просимо до SO. +1 для приємної пропозиції. +1 для посилання "Зоряні війни" в своєму імені користувача. -1 для використання угорської нотації.
додано Автор Christoffer Lette, джерело
Я змінив вашу публікацію. Прочитайте цю публікацію в meta .
додано Автор Christoffer Lette, джерело

Як пишуть інші користувачі, коли ArticleContent не має "." character - метод .Remove() поверне -1.

Я пропоную додати ще одну умову у ваш if :

if (ArticleContent.Length > 260 && ArticleContent.Contains('.'))
{
    ArticleContent = ArticleContent.Remove(ArticleContent.IndexOf('.', 250)) + "...";
}
1
додано

Якщо внизу не вдасться знайти "." воно поверне -1, яке не буде дійсним для RemoveAt

ArticleContent.IndexOf('.', 250)
1
додано

Source of error: '.' does not appear after index 250. The IndexOf method returns -1 in this case.

Хоча інші тільки що визначили джерело помилки, я також опублікую виправлення вашої проблеми.

Solution: Use the LastIndexOf method:

if (ArticleContent.Length > 260)
{
   if (ArticleContent.Remove(ArticleContent.LastIndexOf('.') != -1)
   {
       ArticleContent = String.Concat(ArticleContent.Remove(ArticleContent.LastIndexOf('.')), "...");
   }
   else
   {
       ArticleContent = String.Concat(ArticleContent.Substring(0, 257), "...")
   }
}
0
додано
ArticleContent = ds1.Tables[0].Rows[i]["ArticleContent"].ToString();
if (ArticleContent.Length > 260)
{
    if (ArticleContent.Substring(250).Contains("."))
    {
        ArticleContent = ArticleContent.Remove(ArticleContent.IndexOf('.', 250)) + "...";
    }
    else
    {
        ArticleContent = ArticleContent.Remove(ArticleContent.Substring(0, 250)) + "...";
    }
}
0
додано

Є шанс, що немає. після позиції 250. Потрібно спочатку перевірити:

ArticleContent = ds1.Tables[0].Rows[i]["ArticleContent"].ToString();

var periodPosition = ArticleContent.IndexOf('.', 250);
if (ArticleContent.Length > 260 && periodPosition >= 0)
{
   ArticleContent = ArticleContent.Remove(ArticleContent.IndexOf('.', 250)) + "...";
}
0
додано
var chat = new Chat();
var chat = new Chat();
642 учасників

Обсуждение вопросов по C# / .NET / .NET Core / .NET Standard / Azure Сообщества-организаторы: — @itkpi — @dncuug