Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. Other Discussions
  3. The Weird and The Wonderful
  4. Familiarity : Trimming leading and trailing spaces from a string...

Familiarity : Trimming leading and trailing spaces from a string...

Scheduled Pinned Locked Moved The Weird and The Wonderful
12 Posts 10 Posters 1 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • B Blake Miller

    We can strip leading and trailing spaces from a string….

                int len = strlen((LPSTR)wName);
                while( \*((LPSTR)wName + len - 1) == ' ')
                {
                \*((LPSTR)wName + len - 1) = '\\0';
                len = strlen((LPSTR)wName);
                }                                                                                              
    
                firstNonSpace=((LPSTR)wName);
                while(\*firstNonSpace != '\\0' && isspace(\*firstNonSpace))    
                {          
                    ++firstNonSpace;     
                }     
                len = strlen(firstNonSpace)+1;               
                strcpy((LPSTR)wName, firstNonSpace); 
    

    Or just call… MSDN: “Removes all leading and trailing spaces from a string.”

    PathRemoveBlanks(wName);

    I need a 32 bit unsigned value just to hold the number of coding WTF I see in a day …

    J Offline
    J Offline
    Jecc
    wrote on last edited by
    #3

    I'm no good at Big O notation, but that's some kind of amortized N⁵, isn't it?

    B 1 Reply Last reply
    0
    • J Jecc

      I'm no good at Big O notation, but that's some kind of amortized N⁵, isn't it?

      B Offline
      B Offline
      Blake Miller
      wrote on last edited by
      #4

      1. This code was COPIED to 3 different places - they didn't bother to make a function out of all of it. That is probably the worst error, because now if this 'new' code has bugs, you have to modify three places instead of one. 2. It 'excessively' calculates the length of the string. I think I am being kind here when I say that. 3. 'Familiarity' was my joke - there is already a function in Windows to do this.

      I need a 32 bit unsigned value just to hold the number of coding WTF I see in a day …

      R B 2 Replies Last reply
      0
      • B Blake Miller

        We can strip leading and trailing spaces from a string….

                    int len = strlen((LPSTR)wName);
                    while( \*((LPSTR)wName + len - 1) == ' ')
                    {
                    \*((LPSTR)wName + len - 1) = '\\0';
                    len = strlen((LPSTR)wName);
                    }                                                                                              
        
                    firstNonSpace=((LPSTR)wName);
                    while(\*firstNonSpace != '\\0' && isspace(\*firstNonSpace))    
                    {          
                        ++firstNonSpace;     
                    }     
                    len = strlen(firstNonSpace)+1;               
                    strcpy((LPSTR)wName, firstNonSpace); 
        

        Or just call… MSDN: “Removes all leading and trailing spaces from a string.”

        PathRemoveBlanks(wName);

        I need a 32 bit unsigned value just to hold the number of coding WTF I see in a day …

        J Offline
        J Offline
        Jamercee
        wrote on last edited by
        #5

        Not sure if you are joking, or looking for a serious answer. The code you posted makes WAY too many passes through the source string. If you're looking for maximum performance, you can get this down to just a single pass thusly:

        LPSTR* nxt = wName;

        // find 1st non-whitespace char
        while(*nxt && isspace(*nxt))
        nxt++;

        // if nothing but whitespace
        if (!*np) {
        wName = '\0';
        return wName;
        }

        // save position of 1st non-whitespace
        LPSTR* start = nxt;

        // now find last non-whitespace character
        // before end of line

        LPSTR* last_no_ws = nxt;
        while(*nxt) {
        if (!isspace(*nxt))
        last_no_ws = nxt;
        nxt++;
        }

        // how long is our non-whitespace string?
        int len = (last_no_ws - start) + 1;

        // move the string to beginning of wName
        memmove(wName, start, len);
        wName[len] = '\0';

        return wName;

        You could even save the 'memove' at the end by just modifying the wName string in place (add null after last_no_ws), then return the reference to 'start'. :)

        B 1 Reply Last reply
        0
        • B Blake Miller

          We can strip leading and trailing spaces from a string….

                      int len = strlen((LPSTR)wName);
                      while( \*((LPSTR)wName + len - 1) == ' ')
                      {
                      \*((LPSTR)wName + len - 1) = '\\0';
                      len = strlen((LPSTR)wName);
                      }                                                                                              
          
                      firstNonSpace=((LPSTR)wName);
                      while(\*firstNonSpace != '\\0' && isspace(\*firstNonSpace))    
                      {          
                          ++firstNonSpace;     
                      }     
                      len = strlen(firstNonSpace)+1;               
                      strcpy((LPSTR)wName, firstNonSpace); 
          

          Or just call… MSDN: “Removes all leading and trailing spaces from a string.”

          PathRemoveBlanks(wName);

          I need a 32 bit unsigned value just to hold the number of coding WTF I see in a day …

          M Offline
          M Offline
          Martin0815
          wrote on last edited by
          #6

          Changes: 1. Clear defined end of first loop cutting trailing spaces 2. No undefined behavior of strcpy with overlapping memory areas 3. No unnecessary strlen calls 4. Unified way to test for whitespaces via isspace 5. No warnings because of signed/unsigned conflicts (int <-> unsigned int strlen(...))

          LPSTR myStrTrim(LPSTR pszString)
          {
          LPSTR pszLastChar = pszString + strlen(pszString) - 1;
          while (pszLastChar >= pszString && isspace(*pszLastChar))
          *pszLastChar-- = '\0';

          LPSTR pszFirstChar = pszString;
          while(pszFirstChar < pszLastChar && isspace(\*pszFirstChar))
              ++pszFirstChar;
          
          memmove(pszString, pszFirstChar, pszLastChar-pszFirstChar+1);
          
          return pszString;
          

          }

          1 Reply Last reply
          0
          • B Blake Miller

            We can strip leading and trailing spaces from a string….

                        int len = strlen((LPSTR)wName);
                        while( \*((LPSTR)wName + len - 1) == ' ')
                        {
                        \*((LPSTR)wName + len - 1) = '\\0';
                        len = strlen((LPSTR)wName);
                        }                                                                                              
            
                        firstNonSpace=((LPSTR)wName);
                        while(\*firstNonSpace != '\\0' && isspace(\*firstNonSpace))    
                        {          
                            ++firstNonSpace;     
                        }     
                        len = strlen(firstNonSpace)+1;               
                        strcpy((LPSTR)wName, firstNonSpace); 
            

            Or just call… MSDN: “Removes all leading and trailing spaces from a string.”

            PathRemoveBlanks(wName);

            I need a 32 bit unsigned value just to hold the number of coding WTF I see in a day …

            C Offline
            C Offline
            Chris Boss
            wrote on last edited by
            #7

            One of the best languages for string manipulation is PowerBasic. You can use it to write 32 bit DLL's callable from other languages. To trim leading spaces: LTRIM$(AnyStringVar) To trim any character from left: LTRIM$(AnyStringVar, SomeCharacter) To trim any of multiple characters from left: LTRIM$(AnyStringVar, ANY SomeCharacters) To trim trailing edge spaces: RTRIM$(AnyStringVar) To trim any trailing character: RTRIM$(AnyStringVar,SomeCharacter) To trim any of multiple trailing characters: RTRIM$(AnyStringVar, ANY SomeCharacters) Trim both leading and trailing spaces: TRIM$(AnyStringVar) Trim any character leading or trailing: TRIM$(AnyStringVar, SomeCharacter) Trim any of multiple characters leading and trailing: TRIM$(AnyStringvar, ANY SomeCharacters) PowerBasic supports pointers too ! PowerBasic has many other powerful string functions (both ANSI and UNICODE) such as: ACODE$ - Translate a Unicode string into an ANSI string. BIN$ - Return a string with the binary (base 2) representation of a value. BITS$ - Copies string contents without modification. BUILD$ - Concatenate multiple strings with high efficiency. CHOOSE$ - Return one of several values, based upon the value of an index. CHR$ - Convert one or more character codes into ASCII character(s). CHR$$ - Convert one or more character codes into Unicode character(s). CHRBYTES - Determine the size of a single character in a string variable. ChrToOem$ - Translates a string of ANSI/WIDE characters to OEM byte characters. ChrToUtf8$ - Translates a string of ANSI/WIDE characters to UTF-8 byte characters. CLIP$ - Deletes characters from a string. CLSID$ - Return a 16-byte (128-bit) GUID string containing a CLSID. CSET - Center a string within the space of another string or UDT. CSET$ - Return a string containing a centered (padded) string. DEC$ - Convert an integral value to a decimal string. EXTRACT$ - Return up to the first occurrence of a specified character. FORMAT$ - Return a string containing formatted numeric data. GUID$ - Return a 16-byte (128-bit) Globally Unique Identifier GUID. GUIDTXT$ - Return a 38-byte human-readable GUID/UUID string. HEX$ - Hexadecimal (base 16) string representation of an argument. INSTR - Search a string for the first occurrence of a character or string. JOIN$ - Return a string consisting of all of the strings in a string array. LCASE$ - Return a lowercase version of a string argument. LEFT$ - Return the left

            J 1 Reply Last reply
            0
            • J Jamercee

              Not sure if you are joking, or looking for a serious answer. The code you posted makes WAY too many passes through the source string. If you're looking for maximum performance, you can get this down to just a single pass thusly:

              LPSTR* nxt = wName;

              // find 1st non-whitespace char
              while(*nxt && isspace(*nxt))
              nxt++;

              // if nothing but whitespace
              if (!*np) {
              wName = '\0';
              return wName;
              }

              // save position of 1st non-whitespace
              LPSTR* start = nxt;

              // now find last non-whitespace character
              // before end of line

              LPSTR* last_no_ws = nxt;
              while(*nxt) {
              if (!isspace(*nxt))
              last_no_ws = nxt;
              nxt++;
              }

              // how long is our non-whitespace string?
              int len = (last_no_ws - start) + 1;

              // move the string to beginning of wName
              memmove(wName, start, len);
              wName[len] = '\0';

              return wName;

              You could even save the 'memove' at the end by just modifying the wName string in place (add null after last_no_ws), then return the reference to 'start'. :)

              B Offline
              B Offline
              Blake Miller
              wrote on last edited by
              #8

              This is great. I was just posting the orginal code because of the three reasons I listed. 1. Should be a function - REGARDLESS. 2 - It's inefficient on multiple levels. 3. MS already has the 'tried and true' function to call anyways. I like to see that others do not consider what I posted to be optimal in ANY case, so that is comforting :)

              I need a 32 bit unsigned value just to hold the number of coding WTF I see in a day …

              1 Reply Last reply
              0
              • B Blake Miller

                1. This code was COPIED to 3 different places - they didn't bother to make a function out of all of it. That is probably the worst error, because now if this 'new' code has bugs, you have to modify three places instead of one. 2. It 'excessively' calculates the length of the string. I think I am being kind here when I say that. 3. 'Familiarity' was my joke - there is already a function in Windows to do this.

                I need a 32 bit unsigned value just to hold the number of coding WTF I see in a day …

                R Offline
                R Offline
                RafagaX
                wrote on last edited by
                #9

                Blake Miller wrote:

                if this 'new' code has bugs, you have to modify three places instead of one.

                Or you can create a function with this code and replace the code in the other 3 (and modify just one). :)

                CEO at: - Rafaga Systems - Para Facturas - Modern Components for the moment...

                1 Reply Last reply
                0
                • B Blake Miller

                  1. This code was COPIED to 3 different places - they didn't bother to make a function out of all of it. That is probably the worst error, because now if this 'new' code has bugs, you have to modify three places instead of one. 2. It 'excessively' calculates the length of the string. I think I am being kind here when I say that. 3. 'Familiarity' was my joke - there is already a function in Windows to do this.

                  I need a 32 bit unsigned value just to hold the number of coding WTF I see in a day …

                  B Offline
                  B Offline
                  Brady Kelly
                  wrote on last edited by
                  #10

                  Blake Miller wrote:

                  2. It 'excessively' calculates the length of the string.

                  And just as excessively casts wName to LPSTR.

                  1 Reply Last reply
                  0
                  • C Chris Boss

                    One of the best languages for string manipulation is PowerBasic. You can use it to write 32 bit DLL's callable from other languages. To trim leading spaces: LTRIM$(AnyStringVar) To trim any character from left: LTRIM$(AnyStringVar, SomeCharacter) To trim any of multiple characters from left: LTRIM$(AnyStringVar, ANY SomeCharacters) To trim trailing edge spaces: RTRIM$(AnyStringVar) To trim any trailing character: RTRIM$(AnyStringVar,SomeCharacter) To trim any of multiple trailing characters: RTRIM$(AnyStringVar, ANY SomeCharacters) Trim both leading and trailing spaces: TRIM$(AnyStringVar) Trim any character leading or trailing: TRIM$(AnyStringVar, SomeCharacter) Trim any of multiple characters leading and trailing: TRIM$(AnyStringvar, ANY SomeCharacters) PowerBasic supports pointers too ! PowerBasic has many other powerful string functions (both ANSI and UNICODE) such as: ACODE$ - Translate a Unicode string into an ANSI string. BIN$ - Return a string with the binary (base 2) representation of a value. BITS$ - Copies string contents without modification. BUILD$ - Concatenate multiple strings with high efficiency. CHOOSE$ - Return one of several values, based upon the value of an index. CHR$ - Convert one or more character codes into ASCII character(s). CHR$$ - Convert one or more character codes into Unicode character(s). CHRBYTES - Determine the size of a single character in a string variable. ChrToOem$ - Translates a string of ANSI/WIDE characters to OEM byte characters. ChrToUtf8$ - Translates a string of ANSI/WIDE characters to UTF-8 byte characters. CLIP$ - Deletes characters from a string. CLSID$ - Return a 16-byte (128-bit) GUID string containing a CLSID. CSET - Center a string within the space of another string or UDT. CSET$ - Return a string containing a centered (padded) string. DEC$ - Convert an integral value to a decimal string. EXTRACT$ - Return up to the first occurrence of a specified character. FORMAT$ - Return a string containing formatted numeric data. GUID$ - Return a 16-byte (128-bit) Globally Unique Identifier GUID. GUIDTXT$ - Return a 38-byte human-readable GUID/UUID string. HEX$ - Hexadecimal (base 16) string representation of an argument. INSTR - Search a string for the first occurrence of a character or string. JOIN$ - Return a string consisting of all of the strings in a string array. LCASE$ - Return a lowercase version of a string argument. LEFT$ - Return the left

                    J Offline
                    J Offline
                    Julien Villers
                    wrote on last edited by
                    #11

                    Is that supposed to be a (long) joke or is it just stupid spam?

                    'I'm French! Why do you think I've got this outrrrrageous accent?' Monty Python and the Holy Grail

                    1 Reply Last reply
                    0
                    • B Blake Miller

                      We can strip leading and trailing spaces from a string….

                                  int len = strlen((LPSTR)wName);
                                  while( \*((LPSTR)wName + len - 1) == ' ')
                                  {
                                  \*((LPSTR)wName + len - 1) = '\\0';
                                  len = strlen((LPSTR)wName);
                                  }                                                                                              
                      
                                  firstNonSpace=((LPSTR)wName);
                                  while(\*firstNonSpace != '\\0' && isspace(\*firstNonSpace))    
                                  {          
                                      ++firstNonSpace;     
                                  }     
                                  len = strlen(firstNonSpace)+1;               
                                  strcpy((LPSTR)wName, firstNonSpace); 
                      

                      Or just call… MSDN: “Removes all leading and trailing spaces from a string.”

                      PathRemoveBlanks(wName);

                      I need a 32 bit unsigned value just to hold the number of coding WTF I see in a day …

                      L Offline
                      L Offline
                      Lost User
                      wrote on last edited by
                      #12

                      I feel your pain - points to your signature.

                      1 Reply Last reply
                      0
                      Reply
                      • Reply as topic
                      Log in to reply
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes


                      • Login

                      • Don't have an account? Register

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • World
                      • Users
                      • Groups