Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #140136 > unrolled thread

Function to trim trailing spaces

Started byDFS <nospam@dfs.com>
First post2019-01-23 21:00 -0500
Last post2019-01-24 03:53 -0800
Articles 14 on this page of 54 — 19 participants

Back to article view | Back to comp.lang.c


Contents

  Function to trim trailing spaces DFS <nospam@dfs.com> - 2019-01-23 21:00 -0500
    Re: Function to trim trailing spaces Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2019-01-23 19:14 -0700
      Re: Function to trim trailing spaces DFS <nospam@dfs.com> - 2019-01-23 23:41 -0500
        Re: Function to trim trailing spaces Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2019-01-23 22:40 -0700
          Re: Function to trim trailing spaces Bart <bc@freeuk.com> - 2019-01-24 10:44 +0000
          Re: Function to trim trailing spaces DFS <nospam@dfs.com> - 2019-01-24 11:20 -0500
            Re: Function to trim trailing spaces Bart <bc@freeuk.com> - 2019-01-24 16:47 +0000
              Re: Function to trim trailing spaces DFS <nospam@dfs.com> - 2019-01-24 13:51 -0500
            Re: Function to trim trailing spaces Manfred <noname@invalid.add> - 2019-01-24 17:49 +0100
          Re: Function to trim trailing spaces James Kuyper <jameskuyper@alumni.caltech.edu> - 2019-01-24 08:52 -0800
            Re: Function to trim trailing spaces Bart <bc@freeuk.com> - 2019-01-24 17:40 +0000
            Re: Function to trim trailing spaces James Kuyper <jameskuyper@alumni.caltech.edu> - 2019-01-24 12:08 -0800
              Re: Function to trim trailing spaces Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2019-01-24 14:47 -0700
                Re: Function to trim trailing spaces scott@slp53.sl.home (Scott Lurndal) - 2019-01-25 14:40 +0000
            Re: Function to trim trailing spaces Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2019-01-24 14:44 -0700
        Re: Function to trim trailing spaces Barry Schwarz <schwarzb@dqel.com> - 2019-01-23 23:39 -0800
          Re: Function to trim trailing spaces Rosario19 <Ros@invalid.invalid> - 2019-01-24 10:49 +0100
            Re: Function to trim trailing spaces mark.bluemel@gmail.com - 2019-01-24 01:55 -0800
      Re: Function to trim trailing spaces "Pascal J. Bourguignon" <pjb@informatimago.com> - 2019-01-24 12:58 +0100
      Re: Function to trim trailing spaces Nathan Wagner <nw@hydaspes.if.org> - 2019-01-24 03:01 +0000
    Re: Function to trim trailing spaces Keith Thompson <kst-u@mib.org> - 2019-01-23 18:46 -0800
      Re: Function to trim trailing spaces DFS <nospam@dfs.com> - 2019-01-23 23:38 -0500
        Re: Function to trim trailing spaces Barry Schwarz <schwarzb@dqel.com> - 2019-01-23 23:39 -0800
          Re: Function to trim trailing spaces DFS <nospam@dfs.com> - 2019-01-24 11:25 -0500
            Re: Function to trim trailing spaces mark.bluemel@gmail.com - 2019-01-24 08:34 -0800
            Re: Function to trim trailing spaces Barry Schwarz <schwarzb@dqel.com> - 2019-01-24 15:05 -0800
              Re: Function to trim trailing spaces DFS <nospam@dfs.com> - 2019-01-24 18:40 -0500
        Re: Function to trim trailing spaces Keith Thompson <kst-u@mib.org> - 2019-01-24 02:29 -0800
          Re: Function to trim trailing spaces DFS <nospam@dfs.com> - 2019-01-24 15:06 -0500
            Re: Function to trim trailing spaces Mateusz Viste <mateusz@wont.tell> - 2019-01-24 20:07 +0000
              Re: Function to trim trailing spaces scott@slp53.sl.home (Scott Lurndal) - 2019-01-24 20:24 +0000
                Re: Function to trim trailing spaces Mateusz Viste <mateusz@wont.tell> - 2019-01-24 20:34 +0000
                  Re: Function to trim trailing spaces scott@slp53.sl.home (Scott Lurndal) - 2019-01-24 21:37 +0000
            Re: Function to trim trailing spaces Lew Pitcher <lew.pitcher@digitalfreehold.ca> - 2019-01-24 15:34 -0500
            Re: Function to trim trailing spaces James Kuyper <jameskuyper@alumni.caltech.edu> - 2019-01-24 13:19 -0800
            Re: Function to trim trailing spaces Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2019-01-24 14:52 -0700
              Re: Function to trim trailing spaces James Kuyper <jameskuyper@alumni.caltech.edu> - 2019-01-24 14:30 -0800
                Re: Function to trim trailing spaces Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2019-01-24 16:59 -0700
            Re: Function to trim trailing spaces Keith Thompson <kst-u@mib.org> - 2019-01-24 14:51 -0800
    Re: Function to trim trailing spaces mark.bluemel@gmail.com - 2019-01-24 01:06 -0800
      Re: Function to trim trailing spaces Keith Thompson <kst-u@mib.org> - 2019-01-24 02:13 -0800
        Re: Function to trim trailing spaces mark.bluemel@gmail.com - 2019-01-24 03:46 -0800
      Re: Function to trim trailing spaces Anton Shepelev <anton.txt@g{oogle}mail.com> - 2019-01-24 14:56 +0300
        Re: Function to trim trailing spaces mark.bluemel@gmail.com - 2019-01-24 05:14 -0800
        Re: Function to trim trailing spaces Ben Bacarisse <ben.usenet@bsb.me.uk> - 2019-01-24 18:51 +0000
          Re: Function to trim trailing spaces "Pascal J. Bourguignon" <pjb@informatimago.com> - 2019-01-24 20:04 +0100
            Re: Function to trim trailing spaces Ben Bacarisse <ben.usenet@bsb.me.uk> - 2019-01-24 20:25 +0000
            Re: Function to trim trailing spaces Anton Shepelev <anton.txt@gmail.com> - 2019-01-24 23:50 +0300
          Re: Function to trim trailing spaces Anton Shepelev <anton.txt@gmail.com> - 2019-01-24 23:45 +0300
            Re: Function to trim trailing spaces Anton Shepelev <anton.txt@gmail.com> - 2019-01-24 23:54 +0300
        Re: Function to trim trailing spaces Ralf Damaschke <rwspam@gmx.de> - 2019-01-24 22:43 +0000
    Re: Function to trim trailing spaces Bart <bc@freeuk.com> - 2019-01-24 10:57 +0000
      Re: Function to trim trailing spaces Bart <bc@freeuk.com> - 2019-01-24 23:05 +0000
    Function to trim trailing spaces "I Set My Girlfriend's Pantyhose on Fire" <cdalten@gmail.com> - 2019-01-24 03:53 -0800

Page 3 of 3 — ← Prev page 1 2 [3]


#140149

FromKeith Thompson <kst-u@mib.org>
Date2019-01-24 02:13 -0800
Message-ID<ln5zue1hzb.fsf@kst-u.example.com>
In reply to#140144
mark.bluemel@gmail.com writes:
[...]
> As already mentioned, there are enough obvious ones to
> be going on with.
>
> If ever there was an example of the need for Test
> Driven Development, this looks like it - not because 
> the task is hard, but because programmers need to be
> made to think.
>
> Please tell us what happens when you run the following
> snippets.
>
>   char *s = "my dog has fleas";
>   printf("Before: '%s'\n",str);
>   rtrim(str);
>   printf("After : '%s'\n",str);

It can fail because string literals are read-only.  But who says rtrim()
need to work with read-only data?  There needs to be some documentation
indicating whether it modifies the input or returns a pointer to a new
string.  (The fact that the parameter is defined as char* and not const
char* is IMHO enough to document that fact.  The fact that string
literals are not const is an unfortunate historical artifact.)

[...]

> Here's my 10-minute simplistic hack to do the job.
> The rtrim() function is not elegant, but suffices, and my main
> point is to show some basic ideas about how you could use testing.
> (My more complete example would test the results against expected
> values).
>
> #include <string.h>
> #include <stdio.h>
> #include <stdlib.h>
>
> char *rtrim(char *str) {
>   char * result = strdup(str);

strdup() is defined by POSIX but not by ISO C.  (It's easy enough to
write your own.)

>   int i = strlen(result);

You didn't check whether the allocation failed.

>   for (i = i-1; i >= 0 && result[i]==' '; i--) {
>     result[i] = 0;
>   }
>   return result;
> }
>
> int main(void) {
>
>   char * testStrings[] = {
>     "my dog has no spaces",
>     "my dog has one space ",
>     "my dog has lots of spaces               ",
>     " ",
>     "    "
>   };
>
>   int i;
>
>   for (i = 0; i < sizeof(testStrings)/sizeof(testStrings[0]); i++) {
>     char *trimmed = rtrim(testStrings[i]);
>     printf("before '%s' after '%s'\n", testStrings[i], trimmed);
>     free(trimmed);

This version requires the caller to free the allocated memory, a
drawback that the original function doesn't have.

>   }
>
> }

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Will write code for food.
void Void(void) { Void(); } /* The recursive call of the void */

[toc] | [prev] | [next] | [standalone]


#140154

Frommark.bluemel@gmail.com
Date2019-01-24 03:46 -0800
Message-ID<7a766f98-24fb-472f-a090-943ab0b92286@googlegroups.com>
In reply to#140149
On Thursday, 24 January 2019 10:13:22 UTC, Keith Thompson  wrote:
> mark.bluemel@gmail.com writes:

Thanks for the feedback. I appreciated it.

[toc] | [prev] | [next] | [standalone]


#140157

FromAnton Shepelev <anton.txt@g{oogle}mail.com>
Date2019-01-24 14:56 +0300
Message-ID<20190124145622.e1d84994616505480789e27b@g{oogle}mail.com>
In reply to#140144
Mark Bluemel:

>Here's my 10-minute simplistic hack to do the job.  The
>rtrim() function is not elegant, but suffices, and my main
>point is to show some basic ideas about how you could use
>testing.  (My more complete example would test the results
>against expected values).
>
>#include <string.h>
>#include <stdio.h>
>#include <stdlib.h>
>
>char *rtrim(char *str) {
>  char * result = strdup(str);
>  int i = strlen(result);
>  for (i = i-1; i >= 0 && result[i]==' '; i--) {
>    result[i] = 0;
>  }
>  return result;
>}

Here is my single-pass version:

void rtrim( char * s )
{  char *cur, *trim;
   cur  = s;
   trim = s;
   while( *cur != '\0' )
   {  if( *cur != ' ' ) trim = cur;
      cur++;
   }
   *(trim+1) = '\0';
}

-- 
()  ascii ribbon campaign - against html e-mail
/\  http://preview.tinyurl.com/qcy6mjc [archived]

[toc] | [prev] | [next] | [standalone]


#140161

Frommark.bluemel@gmail.com
Date2019-01-24 05:14 -0800
Message-ID<224d2a31-3260-47ad-8087-e956c3e81f2d@googlegroups.com>
In reply to#140157
On Thursday, 24 January 2019 11:56:29 UTC, Anton Shepelev  wrote:
> Mark Bluemel:
> 
> >Here's my 10-minute simplistic hack to do the job.  The
> >rtrim() function is not elegant, but suffices, and my main
> >point is to show some basic ideas about how you could use
> >testing.  (My more complete example would test the results
> >against expected values).
> >
> >#include <string.h>
> >#include <stdio.h>
> >#include <stdlib.h>
> >
> >char *rtrim(char *str) {
> >  char * result = strdup(str);
> >  int i = strlen(result);
> >  for (i = i-1; i >= 0 && result[i]==' '; i--) {
> >    result[i] = 0;
> >  }
> >  return result;
> >}
> 
> Here is my single-pass version:
> 
> void rtrim( char * s )
> {  char *cur, *trim;
>    cur  = s;
>    trim = s;
>    while( *cur != '\0' )
>    {  if( *cur != ' ' ) trim = cur;
>       cur++;
>    }
>    *(trim+1) = '\0';
> }

Yeah, 2 minutes more and I'd have probably done something similar,
though I'd have probably kept my function prototype, as I'd like
the function to work even if the string was read-only.

My point was more about the idea of testing the functionality with
unit tests than the details of the implementation. This helps the
programmer clarify his requirements by thinking of a suitable
range of inputs and the expected results. 

A simple 'rtrim("my dog has no nose ")' may have raised the question
about read-only, for example.

[toc] | [prev] | [next] | [standalone]


#140181

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2019-01-24 18:51 +0000
Message-ID<87d0olyjli.fsf@bsb.me.uk>
In reply to#140157
Anton Shepelev <anton.txt@g{oogle}mail.com> writes:
<snip>
> Here is my single-pass version:
>
> void rtrim( char * s )
> {  char *cur, *trim;
>    cur  = s;
>    trim = s;
>    while( *cur != '\0' )
>    {  if( *cur != ' ' ) trim = cur;
>       cur++;
>    }
>    *(trim+1) = '\0';
> }

That trims " " to " " and leaves " " unaltered.  I would not expect
that, though trimming spaces when that means all of them is, I suppose,
not well-specified.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#140182

From"Pascal J. Bourguignon" <pjb@informatimago.com>
Date2019-01-24 20:04 +0100
Message-ID<m27eetj2r6.fsf@despina.home>
In reply to#140181
Ben Bacarisse <ben.usenet@bsb.me.uk> writes:

> Anton Shepelev <anton.txt@g{oogle}mail.com> writes:
> <snip>
>> Here is my single-pass version:
>>
>> void rtrim( char * s )
>> {  char *cur, *trim;
>>    cur  = s;
>>    trim = s;
>>    while( *cur != '\0' )
>>    {  if( *cur != ' ' ) trim = cur;
>>       cur++;
>>    }
>>    *(trim+1) = '\0';
>> }
>
> That trims " " to " " and leaves " " unaltered.  I would not expect
> that, though trimming spaces when that means all of them is, I suppose,
> not well-specified.

What's not specified, is mutating literal data, DUH!

-- 
__Pascal J. Bourguignon__
http://www.informatimago.com

[toc] | [prev] | [next] | [standalone]


#140195

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2019-01-24 20:25 +0000
Message-ID<877eetyf9w.fsf@bsb.me.uk>
In reply to#140182
"Pascal J. Bourguignon" <pjb@informatimago.com> writes:

> Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
>
>> Anton Shepelev <anton.txt@g{oogle}mail.com> writes:
>> <snip>
>>> Here is my single-pass version:
>>>
>>> void rtrim( char * s )
>>> {  char *cur, *trim;
>>>    cur  = s;
>>>    trim = s;
>>>    while( *cur != '\0' )
>>>    {  if( *cur != ' ' ) trim = cur;
>>>       cur++;
>>>    }
>>>    *(trim+1) = '\0';
>>> }
>>
>> That trims " " to " " and leaves " " unaltered.  I would not expect
>> that, though trimming spaces when that means all of them is, I suppose,
>> not well-specified.
>
> What's not specified, is mutating literal data, DUH!

Well it's undefined rather than not specified.  Were you taking my " "
examples rather too literally, because there's no code here that does
that?

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#140200

FromAnton Shepelev <anton.txt@gmail.com>
Date2019-01-24 23:50 +0300
Message-ID<20190124235026.c04b0df04450f8ee6048c4d7@gmail.com>
In reply to#140182
Pascal J. Bourguignon:

> What's not specified, is mutating literal data, DUH!

DFS, the original poster, specified his trim function as a
procedure on a pointer to a mutable character object.

-- 
()  ascii ribbon campaign -- against html e-mail
/\  http://preview.tinyurl.com/qcy6mjc [archived]

[toc] | [prev] | [next] | [standalone]


#140199

FromAnton Shepelev <anton.txt@gmail.com>
Date2019-01-24 23:45 +0300
Message-ID<20190124234549.34849ed42ddbb250444b4871@gmail.com>
In reply to#140181
Ben Bacarisse to Anton Shepelev:

> > void rtrim( char * s )
> > {  char *cur, *trim;
> >    cur  = s;
> >    trim = s;
> >    while( *cur != '\0' )
> >    {  if( *cur != ' ' ) trim = cur;
> >       cur++;
> >    }
> >    *(trim+1) = '\0';
> > }
>
> That trims " " to " " and leaves " " unaltered.  I would
> not expect that, though trimming spaces when that means
> all of them is, I suppose, not well-specified.

Well observed!  A quick fix:

void rtrim( char * s )
{  char *cur, *trim;
   cur  = s;
   trim = s;
   while( *cur != '\0' )
   {  if( *cur != ' ' ) trim = cur + 1;
      cur++;
   }
   *(trim) = '\0';
}

A better fix:

void rtrim( char * s )
{  char *cur, *trim;
   cur  = s;
   trim = NULL;
   while( *cur != '\0' )
   {  if( trim == NULL )
      {  if( *cur == ' ' ) trim = cur;   }
      else
      {  if( *cur != ' ' ) trim = NULL;  }
      cur++;
   }
   *(trim) = '\0';
}

-- 
()  ascii ribbon campaign -- against html e-mail
/\  http://preview.tinyurl.com/qcy6mjc [archived]

[toc] | [prev] | [next] | [standalone]


#140201

FromAnton Shepelev <anton.txt@gmail.com>
Date2019-01-24 23:54 +0300
Message-ID<20190124235415.363a4784f3e1bf758018a4cb@gmail.com>
In reply to#140199
I wrote:

> void rtrim( char * s )
> {  char *cur, *trim;
>    cur  = s;
>    trim = NULL;
>    while( *cur != '\0' )
>    {  if( trim == NULL )
>       {  if( *cur == ' ' ) trim = cur;   }
>       else
>       {  if( *cur != ' ' ) trim = NULL;  }
>       cur++;
>    }
>    *(trim) = '\0';
> }

Oh no, it won't work at all.  The last line should be:

  if( trim != NULL ) *(trim) = ' ';

-- 
()  ascii ribbon campaign -- against html e-mail
/\  http://preview.tinyurl.com/qcy6mjc [archived]

[toc] | [prev] | [next] | [standalone]


#140210

FromRalf Damaschke <rwspam@gmx.de>
Date2019-01-24 22:43 +0000
Message-ID<pan.2019.01.24.22.43.56@y2plugh.fqdn.th-h.de>
In reply to#140157
Anton Shepelev schrieb:


> Here is my single-pass version:
> 
> void rtrim( char * s )
> {  char *cur, *trim;
>    cur  = s;
>    trim = s;
>    while( *cur != '\0' )
>    {  if( *cur != ' ' ) trim = cur;
>       cur++;
>    }
>    *(trim+1) = '\0';
> }

That does not work too well with

char foo[] = "\0" "keep away";
rtrim(foo);
printf("<%s> <%s>\n", foo, foo+1);

[toc] | [prev] | [next] | [standalone]


#140153

FromBart <bc@freeuk.com>
Date2019-01-24 10:57 +0000
Message-ID<kSg2E.155219$Pa4.87535@fx30.am4>
In reply to#140136
On 24/01/2019 02:00, DFS wrote:
> Needed to right-trim a string (remove trailing spaces), and came up with 
> this:
> 
> void rtrim(char * s) {s[strlen(s)-1]='\0';}
> 
> 
> 
> test_rtrim.c
> ------------------------------------------------
> #include <stdio.h>
> 
> void rtrim(char * s) {s[strlen(s)-1]='\0';}
> 
> int main(int argc, char *argv[])
> {
>      char str[100];
> 
>      printf("\nEnter some text: ");
>      fgets(str, sizeof(str), stdin);
>      fseek(stdin,0,SEEK_END);  //flush stdin
> 
>      printf("Before: '%s'\n",str);
>      rtrim(str);
>      printf("After : '%s'\n",str);
> }
> ------------------------------------------------
> 
> Seems to work well.  Any unobvious pitfalls?

It's mostly been said I think. Your test method is poor (what's fseek 
got to do with string trimming) and it means that to debug, you have to 
keep typing the same string. Or somehow arrange for input to come from a 
file.

Your main function could just be this:

  int main(int argc, char *argv[])
  {
     char str[] = "one two three four       ";

     printf("Before: '%s'\n",str);
     rtrim(str);
     printf("After : '%s'\n",str);
  }

Your rtrim() function is obviously wrong (it just truncates the last 
character, which isn't well defined for an empty string).

The algorithm might go something like: 'while the string has at least 
one character, and the last character is space (or tab), truncate the 
last character'.

[toc] | [prev] | [next] | [standalone]


#140213

FromBart <bc@freeuk.com>
Date2019-01-24 23:05 +0000
Message-ID<Twr2E.192222$ux2.178255@fx25.am4>
In reply to#140153
On 24/01/2019 10:57, Bart wrote:
> On 24/01/2019 02:00, DFS wrote:
>> Needed to right-trim a string (remove trailing spaces), and came up 
>> with this:
>>
>> void rtrim(char * s) {s[strlen(s)-1]='\0';}

> The algorithm might go something like: 'while the string has at least 
> one character, and the last character is space (or tab), truncate the 
> last character'.
> 

Other people have posted solutions; here's one based closely on that 
algorithm. It's not fast, but once something works, it's much easier to 
make it smaller, tighter, faster if there is a working version to 
compare against:

----------------------
#include <stdio.h>
#include <ctype.h>
#include <string.h>

int lastchar(char* s){
     int length=strlen(s);
     if (length==0) return 0;
     return *(s+length-1);
}

int itruncatelast(char* s){
     int length=strlen(s);
     if (length==0) return 0;
     *(s+length-1)=0;
}

void irtrim(char* s) {

     while (strlen(s)>=1 && isspace(lastchar(s))) {
         itruncatelast(s);
     }
}
----------------------

(This trims spaces, tabs and newlines. For spaces only, just compare the 
lastchar call with ' '.

The 'i' prefix is used to remind you it does an in-place modification.)

[toc] | [prev] | [next] | [standalone]


#140155

From"I Set My Girlfriend's Pantyhose on Fire" <cdalten@gmail.com>
Date2019-01-24 03:53 -0800
Message-ID<3cb86c1f-900f-4cbd-b921-d2212caa2f39@googlegroups.com>
In reply to#140136
Isn't spaces ambiguous anyways? I mean, there is the space that is generated when you press the space bar, and then the spaces produced when you press the tab key.

[toc] | [prev] | [standalone]


Page 3 of 3 — ← Prev page 1 2 [3]

Back to top | Article view | comp.lang.c


csiph-web