94

Building a string for post request in the following way,

  var itemsToAdd = sl.SelProds.ToList();
  if (sl.SelProds.Count() != 0)
  {
      foreach (var item in itemsToAdd)
      {
        paramstr = paramstr + string.Format("productID={0}&", item.prodID.ToString());
      }
  }

after I get resulting paramstr, I need to delete last character & in it

How to delete last character in a string using C#?

rem
  • 16,745
  • 37
  • 112
  • 180
  • 2
    Guess it's better to just not add it in the first place, but otherwise you can try paramstr.Substring(0, paramstr.Length - 1) – Jaco Pretorius Sep 19 '10 at 15:29
  • In case your prodID is allowed to contain arbitrary characters, especially `&`, you need to make sure it gets properly escaped, like e.g. the answer of @MarcGravell does. – Evgeniy Berezovsky Aug 14 '15 at 03:04

10 Answers10

241

Personally I would go with Rob's suggestion, but if you want to remove one (or more) specific trailing character(s) you can use TrimEnd. E.g.

paramstr = paramstr.TrimEnd('&');
Brian Rasmussen
  • 114,645
  • 34
  • 221
  • 317
  • 16
    Be aware that TrimEnd will remove all trailing occurrences of that character '&'... so if the string ends with '&&&' then TrimEnd will remove all 3 of those '&', not just the last one. That may or may not be what the OP wants. – Doug S Apr 03 '14 at 04:50
  • 3
    @DougS FWIW I did writer "remove one (or more)". – Brian Rasmussen Apr 03 '14 at 13:52
  • +1 for a simple solution, that can thus be easily used as a component for other problems. I was searching for a solution to creating a path from multiple parts ensuring I did not have double or missing slashes. Combining TrimEnd and TrimStart with this technique ensures this. – Joeppie Jun 24 '14 at 08:34
  • 1
    @Joeppie: suggest using `Path.Combine`, which understands all path separators. Leastways use `Trim` which does start and end in one go. – Nigel Touch Aug 18 '15 at 16:06
  • @Nigel the trouble I have with Path.Combine is that if the second argument starts with a slash, it is interpreted as an absolute path, and the result is the absolute path; this is something I prefer to 'save' people calling my code from. Good point on the Trim, though :) – Joeppie Aug 05 '16 at 12:13
76

build it with string.Join instead:

var parameters = sl.SelProds.Select(x=>"productID="+x.prodID).ToArray();
paramstr = string.Join("&", parameters);

string.Join takes a seperator ("&") and and array of strings (parameters), and inserts the seperator between each element of the array.

Rob Fonseca-Ensor
  • 15,510
  • 44
  • 57
  • 1
    Worth noting that this is helpful if you don't want to have an & sign at the end of the string. – Ammar Oct 01 '12 at 20:49
  • I knew this was in Ruby, had no idea it was in C# and I'm a .net dev. I feel so embarrassed lol – Jack Marchetti Feb 05 '13 at 20:31
  • I can't believe this was the chosen answer... the one just below this by @BrianRasmussen is so much simpler. – FastTrack Mar 19 '14 at 16:09
  • @FastTrack It solved the root problem, versus answering the question in the title. My complaint: if you are going to be fluent, why not just do it all in one line. – Graham Jul 24 '15 at 21:34
22
string source;
// source gets initialized
string dest;
if (source.Length > 0)
{
    dest = source.Substring(0, source.Length - 1);
}
Steve Townsend
  • 53,498
  • 9
  • 91
  • 140
15

Try this:

paramstr.Remove((paramstr.Length-1),1);
Elmo
  • 6,409
  • 16
  • 72
  • 140
Nelson T Joseph
  • 2,683
  • 8
  • 39
  • 56
  • 2
    Would you consider explaining your answer a little bit, so that others who come along have a better idea why you suggested it? – Andrew Barber Jan 20 '12 at 19:21
  • 1
    [The answer](http://stackoverflow.com/a/15201203/1497596) by @Altaf Patel uses the sibling method [String.Remove Method (Int32)](http://msdn.microsoft.com/en-us/library/9ad138yc%28v=vs.110%29.aspx) which is arguably more straightforward in this situation. However, its good to know about [String.Remove Method (Int32, Int32)](http://msdn.microsoft.com/en-us/library/d8d7z2kk%28v=vs.110%29.aspx) which offers the ability to trim a substring of arbitrary length from anywhere within the source string. – DavidRR Jun 20 '14 at 13:22
13

I would just not add it in the first place:

 var sb = new StringBuilder();

 bool first = true;
 foreach (var foo in items) {
    if (first)
        first = false;
    else
        sb.Append('&');

    // for example:
    var escapedValue = System.Web.HttpUtility.UrlEncode(foo);

    sb.Append(key).Append('=').Append(escapedValue);
 }

 var s = sb.ToString();
Matti Virkkunen
  • 63,558
  • 9
  • 127
  • 159
Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
11
string str="This is test string.";
str=str.Remove(str.Length-1);
Altaf Patel
  • 1,351
  • 1
  • 17
  • 28
  • 1
    From [String.Remove Method (Int32)](http://msdn.microsoft.com/en-us/library/9ad138yc%28v=vs.110%29.aspx): *"Returns a new string in which all the characters in the current instance, beginning at a specified position and continuing through the last position, have been deleted."* – DavidRR Jun 20 '14 at 13:18
7

It's better if you use string.Join.

 class Product
 {
   public int ProductID { get; set; }
 }
 static void Main(string[] args)
 {
   List<Product> products = new List<Product>()
      {   
         new Product { ProductID = 1 },
         new Product { ProductID = 2 },
         new Product { ProductID = 3 }
      };
   string theURL = string.Join("&", products.Select(p => string.Format("productID={0}", p.ProductID)));
   Console.WriteLine(theURL);
 }
Cheng Chen
  • 42,509
  • 16
  • 113
  • 174
5

It's good practice to use a StringBuilder when concatenating a lot of strings and you can then use the Remove method to get rid of the final character.

StringBuilder paramBuilder = new StringBuilder();

foreach (var item in itemsToAdd)
{
    paramBuilder.AppendFormat(("productID={0}&", item.prodID.ToString());
}

if (paramBuilder.Length > 1)
    paramBuilder.Remove(paramBuilder.Length-1, 1);

string s = paramBuilder.ToString();
Dan Diplo
  • 25,076
  • 4
  • 67
  • 89
1
paramstr.Remove((paramstr.Length-1),1);

This does work to remove a single character from the end of a string. But if I use it to remove, say, 4 characters, this doesn't work:

paramstr.Remove((paramstr.Length-4),1);

As an alternative, I have used this approach instead:

DateFrom = DateFrom.Substring(0, DateFrom.Length-4);
DavidRR
  • 18,291
  • 25
  • 109
  • 191
  • 2
    Using [String.Remove Method (Int32, Int32)](http://msdn.microsoft.com/en-us/library/d8d7z2kk%28v=vs.110%29.aspx), to remove **4** characters from the end of a string: `result = source.Remove((source.Length - 4), 4);`. – DavidRR Jun 20 '14 at 13:35
0

Add a StringBuilder extension method.

public static StringBuilder RemoveLast(this StringBuilder sb, string value)
{
    if(sb.Length < 1) return sb;
    sb.Remove(sb.ToString().LastIndexOf(value), value.Length);
    return sb;
}

then use:

yourStringBuilder.RemoveLast(",");
Md Nazmoon Noor
  • 3,187
  • 1
  • 24
  • 30