ArgumentOutOfRangeException

S

shapper

Hello,

I created a string extension to trim a string and add a "..." at the
end if the string was trimmed.

I am getting an error:
Exception Details: System.ArgumentOutOfRangeException: Index was out
of range. Must be non-negative and less than the size of the
collection.
Parameter name: startIndex

On code line:
Int32 i = trimmed.LastIndexOfAny(punctuation, length);

What am I doing wrong?

// ---------- Begin Code ----------

public static void Run() {

String url = "http://domain.com/article/1";
String title = "Lorem Ipsum is simply dummy text of the printing
and typesetting industry. Lorem Ipsum has been the industry's standard
dummy text ever since the 1500s, when an unknown printer took a galley
of type and scrambled it to make a type specimen book. ";

String trimmed = String.Format("{0} {1}", title.Trim(true, 138 -
url.Length), url);

} // Run


public static String Trim(this String value, Boolean ellipsis,
Int32 length) {

// Remove initial empty spaces
value.Trim();

// Check inputs
if (length == 0)
if (ellipsis)
throw new ArgumentOutOfRangeException();
else
return String.Empty;
if (value.Length < length) return value;

// Trim
String trimmed = value.Substring(0, ellipsis ? length - 1 :
length);
Char[] punctuation = { ' ', ',', '.', '?', '!', ':', ';', '-' };
Int32 i = trimmed.LastIndexOfAny(punctuation, length);
if (i != -1)
trimmed = trimmed.Substring(0, i);
return ellipsis ? trimmed + '\x2026' : trimmed;

} // Trim

// ---------- End Code ----------

Thanks,
Miguel
 
A

Alberto Poblacion

shapper said:
I am getting an error:
Exception Details: System.ArgumentOutOfRangeException: Index was out
of range. Must be non-negative and less than the size of the
collection.
Parameter name: startIndex

On code line:
Int32 i = trimmed.LastIndexOfAny(punctuation, length);

On that line, length cannot be greater than trimmed.Length-1, or it would
be out of the allowable range for the index into trimmed. however, the
length of variable "trimmed" in your example is length-1 (set in line String
trimmed = value.Substring(0, ellipsis ? length - 1 : length);), so the
maximum value you can pass to LastIndexOfAny is length-2.

By the way, the line "value.Trim();" does not achieve anything. You
probably want to do "value=value.Trim();".
 
S

shapper

   On that line, length cannot be greater than trimmed.Length-1, or it would
be out of the allowable range for the index into trimmed. however, the
length of variable "trimmed" in your example is length-1 (set in line String
trimmed = value.Substring(0, ellipsis ? length - 1 : length);), so the
maximum value you can pass to LastIndexOfAny is length-2.

I changed it to:

// --- Begin Code ---

public static void Run() {

String url = "http://domain.com/article/123123";
String title = "Lorem Ipsum is simply dummy text of the printing
and typesetting industry. Lorem Ipsum has been the industry's standard
dummy text ever since the 1500s, when an unknown printer took a galley
of type and scrambled it to make a type specimen book. It has survived
not only five centuries, but also the leap into electronic
typesetting, remaining essentially unchanged. It was popularised in
the 1960s with the release of Letraset sheets containing Lorem Ipsum
passages, and more recently with desktop publishing software like
Aldus PageMaker including versions of Lorem Ipsum.";

Int32 l = url.Length;

String trimmed1 = String.Format("{0} {1}", title.Trim(true, 138
- url.Length), url);
Int32 trimmed1Length = trimmed1.Length;

} // Run


public static String Trim(this String value, Boolean ellipsis,
Int32 length) {

// Remove initial empty spaces
value = value.Trim();

// Check inputs
if (length == 0)
if (ellipsis)
throw new ArgumentOutOfRangeException();
else
return String.Empty;
if (value.Length < length)
return value;

// Trim
String trimmed = value.Substring(0, ellipsis ? length - 1 :
length);
Char[] punctuation = { ' ', ',', '.', '?', '!', ':', ';', '-' };
Int32 i = trimmed.LastIndexOfAny(punctuation, 0);
if (i != -1)
trimmed = trimmed.Substring(0, i);
return ellipsis ? trimmed + '\x2026' : trimmed;

} // Trim

// --- End Code ---

So I am defining i as:
Int32 i = trimmed.LastIndexOfAny(punctuation, 0);

Instead of:
Int32 i = trimmed.LastIndexOfAny(punctuation, length);

The problem is that my string is being trimmed by breaking a word ...
I don't want that. I want the string, if needed to be broken, to not
break a word.

I am a little bit lost ... Any idea?
   By the way, the line "value.Trim();" does not achieve anything. You
probably want to do "value=value.Trim();".

I just corrected that. Thank You.
 
A

Alberto Poblacion

shapper said:
[...] So I am defining i as:
Int32 i = trimmed.LastIndexOfAny(punctuation, 0);

This will return -1, since you are searching *backwards* starting at
position 0.

I suggest this instead:

Int32 i = trimmed.LastIndexOfAny(punctuation, trimmed.Length-1);
 
P

Peter Duniho

shapper said:
[...]
So I am defining i as:
Int32 i = trimmed.LastIndexOfAny(punctuation, 0);

Instead of:
Int32 i = trimmed.LastIndexOfAny(punctuation, length);

The problem is that my string is being trimmed by breaking a word ...
I don't want that. I want the string, if needed to be broken, to not
break a word.

I am a little bit lost ... Any idea?

First, it seems to me that it should be acceptable for the string to be
exactly the length asked for, and to return the original string if the
"value.Length <= length" rather than just "value.Length < length".

Second, you seem to be misusing the LastIndexOfAny() method. The index
you pass to it is the starting index, but the method works _backwards_
through the string from that index. If you pass "0" as the starting
index, it won't find any punctuation unless the string starts with
punctuation.

So in your test case, you don't find any punctuation and thus just
truncate the string passed in. Even if you had found punctuation, that
would happen only if the string started with punctuation, and the result
would have been the truncation would remove the entire string, leaving
you with an empty one.

Fortunately, there is an overload of LastIndexOfAny() for which you need
not even concern yourself with the starting index. Just use:

int i = trimmed.LastIndexOfAny(punctuation);

Or, if you really want to specify the index -- which is not a bad idea,
since doing so will allow you to avoid half of the string instances you
are creating here -- then you could change the code so it looks like this:

// Trim
int cchMax = ellipsis ? length - 1 : length;
Char[] punctuation = { ' ', ',', '.', '?', '!', ':', ';', '-' };
Int32 i = trimmed.LastIndexOfAny(punctuation, cchMax - 1);
trimmed = trimmed.Substring(0, i != -1 ? i : cchMax);
return ellipsis ? trimmed + '\x2026' : trimmed;

Hope that helps.

Pete
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

Trim String 9

Top