locked
TrimEnd() doesn't seem to be working. RRS feed

  • Question

  • It's not removing the trail of empty space from my string.

    In my other thread, I have a fixed size structure I'm reading from memory, one of the elements is a string but you cannot directly use a string for this method so I have set it as a byte[24] (the actual name can be anywhere between 1-24 in length, if less than 24 then it will trail spaces until 24 bytes is reached), when I get the name later from the struct I convert it from byte[] to string with the following:


    public static string ByteArrayToString(byte[] bytes)
    {
        System.Text.ASCIIEncoding textEncoding = new System.Text.ASCIIEncoding();
        return textEncoding.GetString(bytes);
    }
    

    I use TrimEnd() with this so I end up with something like this:


    myStruct = GetMyStructure(hProcess, ptrVal);
    myName = Misc.ByteArrayToString(myStruct.name).TrimEnd();
    
    

    But it's not removing the trail, it still comes out as "Example                 ", any ideas?
    Thursday, July 23, 2009 11:09 AM

Answers

  • Don't encode the terminating null character into your string.

    For example:

    using System;
    using System.Text;
    
    class Program
    {
        static void Main( string[] args )
        {
            byte[] bytes1 = new byte[] {65, 32, 32, 0}; // null-terminating byte included (WRONG)
            string str1 = Encoding.ASCII.GetString( bytes1 );
            Console.WriteLine( "\"{0}\"", str1 );
            Console.WriteLine( "\"{0}\"", str1.TrimEnd() );
    
            byte[] bytes2 = new byte[] { 65, 32, 32 }; // no null-terminator (CORRECT!)
            string str2 = Encoding.ASCII.GetString( bytes2 );
            Console.WriteLine( "\"{0}\"", str2 );
            Console.WriteLine( "\"{0}\"", str2.TrimEnd() );
        }
    }
    
    • Proposed as answer by OmegaMan Thursday, July 23, 2009 2:51 PM
    • Marked as answer by Harry Zhu Monday, August 3, 2009 1:06 AM
    Thursday, July 23, 2009 1:04 PM
  • Maybe it's time to post your code that generated "Example                 " then?  (i.e.: the code that displays the result)  You must have missed something in either encoding, trimming, or displaying the result.

    Check that the encoding is correct (that the byte[] buffer contains what it is supposed to, no extraneous trailing characters).
    TrimEnd will work.

    Also check that you are displaying the variable you think you are.

    This would be a classic mistake:
       string a = "foo   ";
       string b = a.Trim();
       Console.WriteLine( a ); // oops!  should be: b

    It's easy to use the debugger to view the contents of the byte[] buffer.  You can even convert the result string back to a byte array in the debugger.
    • Proposed as answer by Harry Zhu Thursday, July 30, 2009 6:01 AM
    • Marked as answer by Harry Zhu Monday, August 3, 2009 1:06 AM
    Monday, July 27, 2009 12:25 PM

All replies

  • Hi There,

    What happenes if you use this -

    myName = Misc.ByteArrayToString(myStruct.name).Trim();

    OR

    myName = Misc.ByteArrayToString(myStruct.name).TrimEnd(' ');

    Regards
    • Edited by IvanRSA Thursday, July 23, 2009 11:56 AM
    Thursday, July 23, 2009 11:52 AM
  • Don't encode the terminating null character into your string.

    For example:

    using System;
    using System.Text;
    
    class Program
    {
        static void Main( string[] args )
        {
            byte[] bytes1 = new byte[] {65, 32, 32, 0}; // null-terminating byte included (WRONG)
            string str1 = Encoding.ASCII.GetString( bytes1 );
            Console.WriteLine( "\"{0}\"", str1 );
            Console.WriteLine( "\"{0}\"", str1.TrimEnd() );
    
            byte[] bytes2 = new byte[] { 65, 32, 32 }; // no null-terminator (CORRECT!)
            string str2 = Encoding.ASCII.GetString( bytes2 );
            Console.WriteLine( "\"{0}\"", str2 );
            Console.WriteLine( "\"{0}\"", str2.TrimEnd() );
        }
    }
    
    • Proposed as answer by OmegaMan Thursday, July 23, 2009 2:51 PM
    • Marked as answer by Harry Zhu Monday, August 3, 2009 1:06 AM
    Thursday, July 23, 2009 1:04 PM
  • That's it, no doubt.  You can't see trailing zeros in the debugger unless you pay really close attention to the double quotes.  Fix:

          s = s.TrimEnd(' ', '\0');


    Hans Passant.
    Thursday, July 23, 2009 1:28 PM
  • Doesn't work, same result.
    Sunday, July 26, 2009 7:57 PM
  • using System.Text.RegularExpressions;

    static void Main(string [] args)
    {
        String word = "Hi             ";
        word = Regex.Replace(word, @"(?:\s{2})+", "").Trim();
        Console.WriteLine(word);
        Console.WriteLine(word.Length);
        Console.ReadLine();
    }
    John Grove - TFD Group, Senior Software Engineer, EI Division, http://www.tfdg.com
    • Edited by JohnGrove Sunday, July 26, 2009 8:55 PM
    Sunday, July 26, 2009 8:48 PM
  • This isn't useful for strings that contain more than one word, it's removing the spaces soitlookslikethis, any other ideas?
    Monday, July 27, 2009 2:35 AM
  • Can you look at the bytes that make up the end of the string to make sure they are all 32s?
    http://blog.voidnish.com
    Monday, July 27, 2009 2:45 AM
  • Maybe it's time to post your code that generated "Example                 " then?  (i.e.: the code that displays the result)  You must have missed something in either encoding, trimming, or displaying the result.

    Check that the encoding is correct (that the byte[] buffer contains what it is supposed to, no extraneous trailing characters).
    TrimEnd will work.

    Also check that you are displaying the variable you think you are.

    This would be a classic mistake:
       string a = "foo   ";
       string b = a.Trim();
       Console.WriteLine( a ); // oops!  should be: b

    It's easy to use the debugger to view the contents of the byte[] buffer.  You can even convert the result string back to a byte array in the debugger.
    • Proposed as answer by Harry Zhu Thursday, July 30, 2009 6:01 AM
    • Marked as answer by Harry Zhu Monday, August 3, 2009 1:06 AM
    Monday, July 27, 2009 12:25 PM
  • This isn't useful for strings that contain more than one word, it's removing the spaces soitlookslikethis, any other ideas?

    Well, you can tweak it some. Use your imagination some.

    using System.Text.RegularExpressions;

    static void Main(string [] args)
    {
        String word = "Hi             ";
        word = Regex.Replace(word, @"(?:\s{2})+", " ").Trim();  //Notice the replaced multiple spaces with just a space, then trim
        Console.WriteLine(word);
        Console.WriteLine(word.Length);
        Console.ReadLine();
    }

    I suspect the issue is what Wyck mentioned. Also, look at Nishant's response and examine the bytes.
    John Grove - TFD Group, Senior Software Engineer, EI Division, http://www.tfdg.com
    Monday, July 27, 2009 1:24 PM