web-dev-qa-db-fra.com

StartIndex ne peut pas être inférieur à zéro. - Erreur en essayant de changer une chaîne

J'ai le code C # suivant:

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

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

Le problème ici est que je reçois ce message d'erreur:

StartIndex ne peut pas être inférieur à zéro.

Pourquoi et comment puis-je résoudre ce problème?

9
Nave Tseva

Vous obtenez cette erreur car il n'y a pas de caractère '.' sur ou après l'index 250, donc IndexOf renvoie -1. Vous essayez ensuite de supprimer le caractère à la position -1 qui vous donne l'erreur que vous voyez.

Sachez également que Remove enlève seulement un caractère à cette position , pas tout ce qui suit cette position . Ce que je soupçonne vous voulez, c'est:

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

Cela ajoutera des ellipses à la chaîne, en s'assurant qu'il ne soit plus que 260 caractères et en cassant à une phrase si possible.

18
D Stanley

Il est clair pourquoi cela échoue, mais que voulez-vous faire exactement? S'il s'agit simplement de tronquer une chaîne à une longueur particulière et d'indiquer la troncature, je pourrais suggérer la méthode d'extension indiquée ci-dessous. Son utilisation est simplement:

ArticleContent = ArticleContent.Truncate(250);

Méthode d'extension tronquée:

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;
}

J'espère que ça aide.

3
AdmiralSnackbar

Si le dessous ne trouve pas le '.' il retournera -1 qui ne sera pas valide pour le RemoveAt

ArticleContent.IndexOf('.', 250)
1
Crab Bucket

Comme d'autres l'ont écrit - quand votre ArticleContent n'a pas de '.' caractère - méthode .Remove() retournera -1.

Je suggère d'ajouter une autre condition dans votre if:

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

Il y a une chance qu'il n'y a pas. après la position 250. Vous devez d'abord vérifier:

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
armen.shimoon

Source de l'erreur: '.' n'apparaît pas après l'index 250. La méthode IndexOf renvoie -1 dans ce cas.

Tandis que d'autres viennent d'identifier la source de l'erreur, je publierai également un correctif pour votre problème.

Solution: Utilisez la méthode LastIndexOf:

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
Derek W
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
Meredith Poor