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


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

Right trim string function in C

Started bypeter <pc722@nospam.mail.com.br>
First post2012-02-10 18:17 +0000
Last post2012-02-12 14:40 +0100
Articles 16 on this page of 56 — 21 participants

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


Contents

  Right trim string function in C peter <pc722@nospam.mail.com.br> - 2012-02-10 18:17 +0000
    Re: Right trim string function in C James Kuyper <jameskuyper@verizon.net> - 2012-02-10 13:36 -0500
      Re: Right trim string function in C Devil with the China Blue Dress <chine.bleu@yahoo.com> - 2012-02-10 11:00 -0800
        Re: Right trim string function in C "BartC" <bc@freeuk.com> - 2012-02-14 12:41 +0000
          Re: Right trim string function in C "BartC" <bc@freeuk.com> - 2012-02-14 14:14 +0000
            Re: Right trim string function in C Ike Naar <ike@iceland.freeshell.org> - 2012-02-15 00:03 +0000
              Re: Right trim string function in C "BartC" <bc@freeuk.com> - 2012-02-15 01:00 +0000
                Re: Right trim string function in C Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-02-15 02:08 +0000
                Re: Right trim string function in C Malcolm McLean <malcolm.mclean5@btinternet.com> - 2012-02-15 03:08 -0800
                  Re: Right trim string function in C gazelle@shell.xmission.com (Kenny McCormack) - 2012-02-15 13:00 +0000
                    Re: Right trim string function in C Kaz Kylheku <kaz@kylheku.com> - 2012-02-16 00:36 +0000
                Re: Right trim string function in C Kaz Kylheku <kaz@kylheku.com> - 2012-02-16 00:28 +0000
                Re: Right trim string function in C gordonb.7bjv1@burditt.org (Gordon Burditt) - 2012-03-12 03:27 -0500
                  Re: Right trim string function in C China Blue Water Navy <chine.bleu@yahoo.com> - 2012-03-12 03:57 -0800
          Re: Right trim string function in C Devil with the China Blue Dress <chine.bleu@yahoo.com> - 2012-02-14 09:59 -0800
        Re: Right trim string function in C Kaz Kylheku <kaz@kylheku.com> - 2012-02-14 12:56 +0000
          Re: Right trim string function in C Devil with the China Blue Dress <chine.bleu@yahoo.com> - 2012-02-14 09:17 -0800
          Re: Right trim string function in C Malcolm McLean <malcolm.mclean5@btinternet.com> - 2012-02-14 10:10 -0800
    Re: Right trim string function in C Barry Schwarz <schwarzb@dqel.com> - 2012-02-10 11:30 -0800
      Re: Right trim string function in C James Kuyper <jameskuyper@verizon.net> - 2012-02-10 14:45 -0500
        Re: Right trim string function in C Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-02-10 22:15 +0000
          Re: Right trim string function in C James Kuyper <jameskuyper@verizon.net> - 2012-02-10 17:21 -0500
            Re: Right trim string function in C Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-02-10 23:25 +0000
            Re: Right trim string function in C Keith Thompson <kst-u@mib.org> - 2012-02-10 15:31 -0800
        Re: Right trim string function in C pete <pfiland@mindspring.com> - 2012-02-10 17:17 -0500
          Re: Right trim string function in C Devil with the China Blue Dress <chine.bleu@yahoo.com> - 2012-02-10 15:12 -0800
    Re: Right trim string function in C "Morris Keesan" <mkeesan@post.harvard.edu> - 2012-02-10 14:46 -0500
      Re: Right trim string function in C Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-02-10 21:56 +0000
        Re: Right trim string function in C James Kuyper <jameskuyper@verizon.net> - 2012-02-10 17:08 -0500
          Re: Right trim string function in C Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-02-10 23:14 +0000
            Re: Right trim string function in C David Thompson <dave.thompson2@verizon.net> - 2012-02-18 23:11 -0500
        Re: Right trim string function in C Keith Thompson <kst-u@mib.org> - 2012-02-11 12:06 -0800
        Re: Right trim string function in C Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-02-11 20:12 +0000
        Re: Right trim string function in C Tim Rentsch <txr@alumni.caltech.edu> - 2012-03-08 13:10 -0800
    Re: Right trim string function in C "Scott Fluhrer" <sfluhrer@ix.netcom.com> - 2012-02-10 15:39 -0500
    Re: Right trim string function in C Shao Miller <sha0.miller@gmail.com> - 2012-02-11 03:52 -0500
      Re: Right trim string function in C Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-02-11 13:50 +0000
        Re: Right trim string function in C Shao Miller <sha0.miller@gmail.com> - 2012-02-11 11:47 -0500
          Re: Right trim string function in C Shao Miller <sha0.miller@gmail.com> - 2012-02-11 12:20 -0500
          Re: Right trim string function in C Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-02-11 20:57 +0000
            Re: Right trim string function in C Shao Miller <sha0.miller@gmail.com> - 2012-02-11 17:43 -0500
    Re: Right trim string function in C Willem <willem@toad.stack.nl> - 2012-02-11 11:57 +0000
      Re: Right trim string function in C Willem <willem@toad.stack.nl> - 2012-02-11 18:11 +0000
    Re: Right trim string function in C August Karlstrom <fusionfile@gmail.com> - 2012-02-11 18:41 +0100
      Re: Right trim string function in C Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-02-11 19:58 +0000
        Re: Right trim string function in C Malcolm McLean <malcolm.mclean5@btinternet.com> - 2012-02-11 13:11 -0800
        Re: Right trim string function in C August Karlstrom <fusionfile@gmail.com> - 2012-02-11 22:18 +0100
          Re: Right trim string function in C Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-02-11 23:48 +0000
            Re: Right trim string function in C August Karlstrom <fusionfile@gmail.com> - 2012-02-12 02:20 +0100
            Re: Right trim string function in C Malcolm McLean <malcolm.mclean5@btinternet.com> - 2012-02-12 03:44 -0800
              Re: Right trim string function in C Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-02-12 14:01 +0000
                Re: Right trim string function in C Malcolm McLean <malcolm.mclean5@btinternet.com> - 2012-02-12 11:06 -0800
                  Re: Right trim string function in C Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-02-12 19:34 +0000
                    Re: Right trim string function in C Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-02-12 23:35 +0000
      Re: Right trim string function in C Barry Schwarz <schwarzb@dqel.com> - 2012-02-11 14:27 -0800
        Re: Right trim string function in C August Karlstrom <fusionfile@gmail.com> - 2012-02-12 14:40 +0100

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


#17146

FromShao Miller <sha0.miller@gmail.com>
Date2012-02-11 17:43 -0500
Message-ID<jh6qpf$u7e$1@dont-email.me>
In reply to#17126
On 2/11/2012 15:57, Ben Bacarisse wrote:
> Shao Miller<sha0.miller@gmail.com>  writes:
>
>> On 2/11/2012 08:50, Ben Bacarisse wrote:
>>> Shao Miller<sha0.miller@gmail.com>   writes:
>>>
>>>> On 2/10/2012 13:17, peter wrote:
>>>>> Hello C programmers,
>>>>>            I was wondering does anybody knows how or is there
>>>>> a right trim string function available in C?
>>>>>
>>>>>            Eg. Suppose I have the following:
>>>>>
>>>>>               char *str = "Hello Dolly     \0";
>>>>>
>>>>>            Is there a right trim function that will remove the
>>>>> trailing spaces and make *str look like "Hello Dolly\0"?
>>>>>
>>>>> In PYTHON there is a useful function for this: str.rstrip();
>>>>
>>>> Maybe you would like this?:
>>>>
>>>
>>> This is a very good effort, but, I am sorry to say, I was able to
>>> understand it eventually.
>>
>> No need to apologize.  I'm glad that you eventually understood it
>> without any comments to follow along with.  If it had been a more
>> instructive example, it would have included comments.
>
> My post was an attempt at humour that seems to have failed.  Sorry about
> that.

I suspected, but wasn't 100% sure.  Now that it's certain, I'll say that 
the post was pretty funny, even if thoroughly punishing. :)

> Because style discussions are generally unproductive (people who
> use non-standard styles always know that the reasons they do it are
> worth it) I wanted to say "Personally, I don't like your choices and BTW
> you forgot to include ctype.h" in a more interesting way than that.
>
> I'm sorry if it was not funny.
>

It was.  It's still too bad that it doesn't appeal to everyone, though, 
and is worth consideration in a group project.

>>> You might want to study the code posted by
>>> Stefan Ram.
> <snip>
>>> He is undoubtedly ahead of you in matters of pure layout,
>>
>> What do you mean?  Stylistically?  In regards to program flow?  In
>> regards to object usage?  His program and mine do different things,
>> so...
>
> Yes, stylistically.  I find his highly non-standard layout very hard to
> read.
>

')*p ' threw me off for a few seconds.

>>> but your use of a little-used statement in a position where it is both
>>> suggestive and pointless is a stoke of genius!
>>
>> Are you referring to the keyword (not statement) 'register'?
>
> No, as you later posted it was the continue at the bottom of every loop.
>

++oops; --oops;

>>   If so,
>> it's a storage-class specifier.  While it suggests that access to
>> so-specified objects "be as fast as possible," it also ensures that
>> the address of a so-specified object cannot be taken.  In this
>> fashion, it is used in my code to prevent accidentally taking the
>> address of the corresponding objects.
>
> You see?  I was sure you'd have a reason for that,  Just chuckle at my
> Luddite failure to perceive the value of it.
>

*Chuckle*

> <snip>
>>> As for the semantics, I thought the idea of keeping "one_past_end" one
>>> greater than it needs to be (thereby toying, teasingly, with UB all the
>>> time) was a very nice touch -- it's always nice to see a '+ 2' in a
>>> string-walking loop.
>>
>> Why is it one greater than it needs to be?  If 'c' is not the null
>> terminator, then one past the end of the string is at least two
>> characters away.  That distance seems useful for the 'malloc'.
>
> It's swings and roundabouts.  You need to --diff to set the null and do
> the memcpy and if you keep the pointer "nearer" you need to +1 when you
> malloc.  The latter is, at least, a common idiom.  I.e.:
>
>       char c;
>       const char * cur_pos = string;
>       const char * one_past_end = string;
>       ptrdiff_t diff;
>       char * copy;
>
>       if (!chars) {
>            while ((c = *cur_pos++))
>                 if (!isspace(c))
>                      one_past_end = cur_pos;
>       }
>       else {
>            while ((c = *cur_pos++))
>                 if (!in_set(c, chars))
>                      one_past_end = cur_pos;
>       }
>       diff = one_past_end - string;
>       copy = malloc(diff + 1);
>       if (!copy)
>            return NULL;
>
>       copy[diff] = '\0';
>       return memcpy(copy, string, diff);
>

Yes, that does seem to be a more common approach that I've seen.  I 
guess that I figured this 'diff + 1' idiom above would be implemented in 
one of two ways:

   increment the register for 'diff'
   use that with 'malloc'
   decrement it back to what it was
   use that with the last two lines

or:

   copy 'diff' into another register B
   increment that other register B
   use that B with 'malloc'
   register B is free for repurposing

Neither of which I particularly care for, versus:

   use 'diff' with 'malloc'
   decrement 'diff'
   use that with the last two lines

Since both flavours use 'one_past_end' and 'cur_pos', I figured the 
earlier 'one_past_end = cur_pos + 2' would probably go:

   copy 'cur_pos' into 'one_past_end'
   increment 'one_past_end'
   increment 'one_past_end'

But of course, these are totally wild assumptions.

> Personally, I'd then change "diff" to "length".  I've also moved the ++
> of cur_pos to the loop, but if you don't like that you can go back to
>
>       while ((c = *cur_pos)) {
>           if (!isspace(c))
>               one_past_end = cur_pos + 1;
>           ++cur_pos;
>       }
>
> but it's then clear that the ++cur_pos could go above the "if" and thus
> into the loop condition.

Actually, I prefer '*cur_pos++' (and had that originally), but thought 
it might be too wild for the OP, for whatever reason.  However, since 
there aren't any comments to follow along with, it's weak for any 
instructional consideration, anyway.

Pleasant discussion, though! :)

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


#17109

FromWillem <willem@toad.stack.nl>
Date2012-02-11 11:57 +0000
Message-ID<slrnjjclsu.29k8.willem@toad.stack.nl>
In reply to#17069
peter wrote:
) Hello C programmers,
)         I was wondering does anybody knows how or is there
) a right trim string function available in C?    
)
)         Eg. Suppose I have the following:
)
)            char *str = "Hello Dolly     \0";
)
)         Is there a right trim function that will remove the
) trailing spaces and make *str look like "Hello Dolly\0"?
)
) In PYTHON there is a useful function for this: str.rstrip();

There's been a lot of code posted, all of which seemed to be using
pointers, so just for shits I'll post one that uses indexes:

i = strlen(s);
while (i > 0 && s[i-1] == ' ') i--;
s2 = malloc(i+1);
memcpy(s2, s, i);
s2[i] = 0;


SaSW, Willem
-- 
Disclaimer: I am in no way responsible for any of the statements
            made in the above text. For all I know I might be
            drugged or something..
            No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT

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


#17115

FromWillem <willem@toad.stack.nl>
Date2012-02-11 18:11 +0000
Message-ID<slrnjjdbr5.nk1.willem@toad.stack.nl>
In reply to#17109
Willem wrote:
) peter wrote:
) ) Hello C programmers,
) )         I was wondering does anybody knows how or is there
) ) a right trim string function available in C?    
) )
) )         Eg. Suppose I have the following:
) )
) )            char *str = "Hello Dolly     \0";
) )
) )         Is there a right trim function that will remove the
) ) trailing spaces and make *str look like "Hello Dolly\0"?
) )
) ) In PYTHON there is a useful function for this: str.rstrip();
)
) There's been a lot of code posted, all of which seemed to be using
) pointers, so just for shits I'll post one that uses indexes:
)
) i = strlen(s);
) while (i > 0 && s[i-1] == ' ') i--;
) s2 = malloc(i+1);
) memcpy(s2, s, i);
) s2[i] = 0;

And if you really want to avoid the forwards/backwards seeking,
(but note that strlen is probably a lot faster at seeking forward than
 a manual loop, so for long strings this could very well be slower)
use this:

i = 0;
for (j = 0; s[j]; j++) if (s[j] != ' ') i = j+1;
s2 = malloc(i+1);
memcpy(s2, s, i);
s2[i] = 0;

But like I said, that will probably be slower in most cases.


SaSW, Willem
-- 
Disclaimer: I am in no way responsible for any of the statements
            made in the above text. For all I know I might be
            drugged or something..
            No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT

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


#17114

FromAugust Karlstrom <fusionfile@gmail.com>
Date2012-02-11 18:41 +0100
Message-ID<jh697n$mi8$1@dont-email.me>
In reply to#17069
On 2012-02-10 19:17, peter wrote:
> Hello C programmers,
>          I was wondering does anybody knows how or is there
> a right trim string function available in C?

No, not in the standard library, but it is not hard to implement. 
Remember that since strings are constant objects you first need to copy 
the string to a character array.

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

void trim_right(char *s)
{
	int i;
	
	i = strlen(s) - 1;
	while ((i >= 0) && isspace(s[i])) {
		i--;
	}
	s[i + 1] = '\0';
}


August

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


#17119

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2012-02-11 19:58 +0000
Message-ID<0.eb9addb08316dfd98bab.20120211195810GMT.87mx8pb0rx.fsf@bsb.me.uk>
In reply to#17114
August Karlstrom <fusionfile@gmail.com> writes:

> On 2012-02-10 19:17, peter wrote:
>> Hello C programmers,
>>          I was wondering does anybody knows how or is there
>> a right trim string function available in C?
>
> No, not in the standard library, but it is not hard to
> implement. Remember that since strings are constant objects you first
> need to copy the string to a character array.
>
> #include <ctype.h>
> #include <string.h>
>
> void trim_right(char *s)
> {
> 	int i;
> 	
> 	i = strlen(s) - 1;
> 	while ((i >= 0) && isspace(s[i])) {
> 		i--;
> 	}
> 	s[i + 1] = '\0';
> }

Odd things can happen when strlen(s) == 0 because strlen(s) - 1 is a
large positive number which may or may not fit into an int (it's worse
if it does, though that is very unlikely).  Of course, since the
conversion to int is implementation defined, you may get -1 exactly as
you expect, but that just means the problem might not show up in
testing.  You can avoid the problem by sticking to unsigned arithmetic:

  size_t i = strlen(s);
  while (i-- > 0 && isspace(s[i]))
      /* do nothing */;
  s[i + 1] = '\0';

Using unsigned wrap-around like this is a little unusual but it does
work (unless I've messed-up of course).

-- 
Ben.

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


#17129

FromMalcolm McLean <malcolm.mclean5@btinternet.com>
Date2012-02-11 13:11 -0800
Message-ID<17612ebf-b5f6-4eac-843b-6d5ae257d69a@a15g2000yqf.googlegroups.com>
In reply to#17119
On Feb 11, 7:58 pm, Ben Bacarisse <ben.use...@bsb.me.uk> wrote:
> August Karlstrom <fusionf...@gmail.com> writes:
> > On 2012-02-10 19:17, peter wrote:
> >> Hello C programmers,
> >>          I was wondering does anybody knows how or is there
> >> a right trim string function available in C?
>
> > No, not in the standard library, but it is not hard to
> > implement. Remember that since strings are constant objects you first
> > need to copy the string to a character array.
>
> > #include <ctype.h>
> > #include <string.h>
>
> > void trim_right(char *s)
> > {
> >    int i;
>
> >    i = strlen(s) - 1;
> >    while ((i >= 0) && isspace(s[i])) {
> >            i--;
> >    }
> >    s[i + 1] = '\0';
> > }
>
> Odd things can happen when strlen(s) == 0 because strlen(s) - 1 is a
> large positive number which may or may not fit into an int (it's worse
> if it does, though that is very unlikely).  Of course, since the
> conversion to int is implementation defined, you may get -1 exactly as
> you expect, but that just means the problem might not show up in
> testing.  You can avoid the problem by sticking to unsigned arithmetic:
>
>   size_t i = strlen(s);
>   while (i-- > 0 && isspace(s[i]))
>       /* do nothing */;
>   s[i + 1] = '\0';
>
> Using unsigned wrap-around like this is a little unusual but it does
> work (unless I've messed-up of course).
>
> --
> Ben.- Hide quoted text -
>
> - Show quoted text -

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


#17130

FromAugust Karlstrom <fusionfile@gmail.com>
Date2012-02-11 22:18 +0100
Message-ID<jh6lv3$3pf$1@dont-email.me>
In reply to#17119
On 2012-02-11 20:58, Ben Bacarisse wrote:
> August Karlstrom<fusionfile@gmail.com>  writes:
>> #include<ctype.h>
>> #include<string.h>
>>
>> void trim_right(char *s)
>> {
>> 	int i;
>> 	
>> 	i = strlen(s) - 1;
>> 	while ((i>= 0)&&  isspace(s[i])) {
>> 		i--;
>> 	}
>> 	s[i + 1] = '\0';
>> }
>
> Odd things can happen when strlen(s) == 0 because strlen(s) - 1 is a
> large positive number which may or may not fit into an int (it's worse
> if it does, though that is very unlikely).  Of course, since the
> conversion to int is implementation defined, you may get -1 exactly as
> you expect, but that just means the problem might not show up in
> testing.

Thanks for pointing that out. I somewhat carelessly assumed that strlen 
returns an int.

> You can avoid the problem by sticking to unsigned arithmetic:
>
>    size_t i = strlen(s);
>    while (i-->  0&&  isspace(s[i]))
>        /* do nothing */;
>    s[i + 1] = '\0';
>
> Using unsigned wrap-around like this is a little unusual but it does
> work (unless I've messed-up of course).

For empty strings and strings containing only whitespace you rely on two 
unsigned integer wrap-arounds. Nothing wrong with that, though I find 
the side-effectful loop guard hard to understand - could you maybe read 
its meaning aloud. ;-)

Sometimes unsigned types create more problems than they solve so I would 
probably just make sure that the string is not insanely long:

#include <assert.h>
#include <ctype.h>
#include <limits.h>
#include <string.h>

void trim_right(char *s)
{
	size_t len;
	int i;
	
	len = strlen(s);
	assert(len <= INT_MAX);
	i = len - 1;
	while ((i >= 0) && isspace(s[i])) {
		i--;
	}
	s[i + 1] = '\0';
}


August

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


#17157

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2012-02-11 23:48 +0000
Message-ID<0.df5494a160a09c5a7df4.20120211234839GMT.877gzt9bjc.fsf@bsb.me.uk>
In reply to#17130
August Karlstrom <fusionfile@gmail.com> writes:

> On 2012-02-11 20:58, Ben Bacarisse wrote:
<snip>
>> You can avoid the problem by sticking to unsigned arithmetic:
>>
>>    size_t i = strlen(s);
>>    while (i-->  0&&  isspace(s[i]))
>>        /* do nothing */;
>>    s[i + 1] = '\0';
>>
>> Using unsigned wrap-around like this is a little unusual but it does
>> work (unless I've messed-up of course).
>
> For empty strings and strings containing only whitespace you rely on
> two unsigned integer wrap-arounds. Nothing wrong with that, though I
> find the side-effectful loop guard hard to understand - could you
> maybe read its meaning aloud. ;-)

Some spaces have got lost.  My post had 'i-- > 0 && isspace(s[i])' and
no, I can't read it out load.  That's interesting, because I can see
that it might be an advantage to be able to, but I just think of complex
conditions involving && as chains of actions and side effects and so it
looks quite normal to me.

> Sometimes unsigned types create more problems than they solve so I
> would probably just make sure that the string is not insanely long:
>
> #include <assert.h>
> #include <ctype.h>
> #include <limits.h>
> #include <string.h>
>
> void trim_right(char *s)
> {
> 	size_t len;
> 	int i;
> 	
> 	len = strlen(s);
> 	assert(len <= INT_MAX);
> 	i = len - 1;

That won't help because the problem comes when strlen(s) == 0.  Maybe
you intended to write:

	len = strlen(s);
	assert(len <= INT_MAX);
	i = len;
        i -= 1;

?  It's odd enough to deserve a comment, though.

> 	while ((i >= 0) && isspace(s[i])) {
> 		i--;
> 	}
> 	s[i + 1] = '\0';
> }

-- 
Ben.

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


#17162

FromAugust Karlstrom <fusionfile@gmail.com>
Date2012-02-12 02:20 +0100
Message-ID<jh7446$g70$1@dont-email.me>
In reply to#17157
On 2012-02-12 00:48, Ben Bacarisse wrote:
> Some spaces have got lost.  My post had 'i-->  0&&  isspace(s[i])' and
> no,

Sorry about that, it is caused by a bug in my email client (Thunderbid
9.0) though I have not noticed it before.

https://bugzilla.mozilla.org/show_bug.cgi?id=448198

> I can't read it out load.  That's interesting, because I can see
> that it might be an advantage to be able to, but I just think of complex
> conditions involving&&  as chains of actions and side effects and so it
> looks quite normal to me.

I see, like shell commands in Bash. My own ideal is to build
abstractions from very simple parts (expressions and statements).

>> 	size_t len;
>> 	int i;
>> 	
>> 	len = strlen(s);
>> 	assert(len<= INT_MAX);
>> 	i = len - 1;
>
> That won't help because the problem comes when strlen(s) == 0.

Yes, you are right. I forgot to cast len to int, the statement should be

i = (int) len - 1;


August

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


#17169

FromMalcolm McLean <malcolm.mclean5@btinternet.com>
Date2012-02-12 03:44 -0800
Message-ID<6e213178-a86a-4c2a-b70f-099d47914d90@b23g2000yqn.googlegroups.com>
In reply to#17157
On Feb 11, 11:48 pm, Ben Bacarisse <ben.use...@bsb.me.uk> wrote:
> August Karlstrom <fusionf...@gmail.com> writes:
> > On 2012-02-11 20:58, Ben Bacarisse wrote:
> <snip>
> >> You can avoid the problem by sticking to unsigned arithmetic:
>
> >>    size_t i = strlen(s);
> >>    while (i-->  0&&  isspace(s[i]))
> >>        /* do nothing */;
> >>    s[i + 1] = '\0';
>
> >> Using unsigned wrap-around like this is a little unusual but it does
> >> work (unless I've messed-up of course).
>
> > For empty strings and strings containing only whitespace you rely on
> > two unsigned integer wrap-arounds. Nothing wrong with that, though I
> > find the side-effectful loop guard hard to understand - could you
> > maybe read its meaning aloud. ;-)
>
> Some spaces have got lost.  My post had 'i-- > 0 && isspace(s[i])' and
> no, I can't read it out load.  That's interesting, because I can see
> that it might be an advantage to be able to, but I just think of complex
> conditions involving && as chains of actions and side effects and so it
> looks quite normal to me.
>
>
>
>
>
> > Sometimes unsigned types create more problems than they solve so I
> > would probably just make sure that the string is not insanely long:
>
> > #include <assert.h>
> > #include <ctype.h>
> > #include <limits.h>
> > #include <string.h>
>
> > void trim_right(char *s)
> > {
> >    size_t len;
> >    int i;
>
> >    len = strlen(s);
> >    assert(len <= INT_MAX);
> >    i = len - 1;
>
> That won't help because the problem comes when strlen(s) == 0.  Maybe
> you intended to write:
>
>         len = strlen(s);
>         assert(len <= INT_MAX);
>         i = len;
>         i -= 1;
>
> ?  It's odd enough to deserve a comment, though.
>
> >    while ((i >= 0) && isspace(s[i])) {
> >            i--;
> >    }
> >    s[i + 1] = '\0';
> > }
>
i = strlen(s);
while(i--)
  if(!isspace(s[i]))
    break;
s[i+1] = '\0';

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


#17175

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2012-02-12 14:01 +0000
Message-ID<0.8a7577ecf4ba171e2b31.20120212140157GMT.87zkco8816.fsf@bsb.me.uk>
In reply to#17169
Malcolm McLean <malcolm.mclean5@btinternet.com> writes:
<snip>
>> > On 2012-02-11 20:58, Ben Bacarisse wrote:
>> <snip>
>> >> You can avoid the problem by sticking to unsigned arithmetic:
>>
>> >>    size_t i = strlen(s);
>> >>    while (i-- > 0 && isspace(s[i]))
>> >>        /* do nothing */;
>> >>    s[i + 1] = '\0';
>>
>> >> Using unsigned wrap-around like this is a little unusual but it does
>> >> work (unless I've messed-up of course).
<snip>
> i = strlen(s);
> while(i--)
>   if(!isspace(s[i]))
>     break;
> s[i+1] = '\0';

As you can see that's what I was advocating.  Are you saying that
putting

  if (!C) break;

in a loop is better that just adding '&& C' to the loop condition?  I
prefer to have an explicit loop condition.  I'm neutral about your other
change (from 'i-- > 0' to 'i--' on it's own).

-- 
Ben.

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


#17177

FromMalcolm McLean <malcolm.mclean5@btinternet.com>
Date2012-02-12 11:06 -0800
Message-ID<63f58cd3-e15f-46a7-9e3b-6d8633d65d73@k10g2000yqk.googlegroups.com>
In reply to#17175
On Feb 12, 2:01 pm, Ben Bacarisse <ben.use...@bsb.me.uk> wrote:
> Malcolm McLean <malcolm.mcle...@btinternet.com> writes:
>
> <snip>
>
>
>
>
>
> >> > On 2012-02-11 20:58, Ben Bacarisse wrote:
> >> <snip>
> >> >> You can avoid the problem by sticking to unsigned arithmetic:
>
> >> >>    size_t i = strlen(s);
> >> >>    while (i-- > 0 && isspace(s[i]))
> >> >>        /* do nothing */;
> >> >>    s[i + 1] = '\0';
>
> >> >> Using unsigned wrap-around like this is a little unusual but it does
> >> >> work (unless I've messed-up of course).
> <snip>
> > i = strlen(s);
> > while(i--)
> >   if(!isspace(s[i]))
> >     break;
> > s[i+1] = '\0';
>
> As you can see that's what I was advocating.  Are you saying that
> putting
>
>   if (!C) break;
>
> in a loop is better that just adding '&& C' to the loop condition?
>
while(i-- > 0 && isspace(s[i]))
   /* do nothing*/;

is a bit confusing. First, you have an empty loop. Then in fact i is
decremented before the test s[i], and it's safe because of intellignet
and guarding. That's exactly the sort of detail that people who only
use C occasionally often get wrong.
i = N;
while(i--)
  is idiomatic C for counting down.


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


#17178

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2012-02-12 19:34 +0000
Message-ID<0.9ad07a6547ede9a57ab5.20120212193450GMT.87ty2v976t.fsf@bsb.me.uk>
In reply to#17177
Malcolm McLean <malcolm.mclean5@btinternet.com> writes:

> On Feb 12, 2:01 pm, Ben Bacarisse <ben.use...@bsb.me.uk> wrote:
>> Malcolm McLean <malcolm.mcle...@btinternet.com> writes:
>>
>> <snip>
>>
>> >> > On 2012-02-11 20:58, Ben Bacarisse wrote:
>> >> <snip>
>> >> >> You can avoid the problem by sticking to unsigned arithmetic:
>>
>> >> >>    size_t i = strlen(s);
>> >> >>    while (i-- > 0 && isspace(s[i]))
>> >> >>        /* do nothing */;
>> >> >>    s[i + 1] = '\0';
>>
>> >> >> Using unsigned wrap-around like this is a little unusual but it does
>> >> >> work (unless I've messed-up of course).
>> <snip>
>> > i = strlen(s);
>> > while(i--)
>> >   if(!isspace(s[i]))
>> >     break;
>> > s[i+1] = '\0';
>>
>> As you can see that's what I was advocating.  Are you saying that
>> putting
>>
>>   if (!C) break;
>>
>> in a loop is better that just adding '&& C' to the loop condition?
>>
> while(i-- > 0 && isspace(s[i]))
>    /* do nothing*/;
>
> is a bit confusing. First, you have an empty loop. Then in fact i is
> decremented before the test s[i], and it's safe because of intellignet
> and guarding. That's exactly the sort of detail that people who only
> use C occasionally often get wrong.

Your version also depends on exactly the same details of guarding so if
it's wrong in my version, it will be wrong in yours.  That point can't
be an argument either way.

You've exchanged an empty loop for another exit from the loop.  I don't
think that's a good exchange but I accept that's partly just a matter of
taste.  You don't (presumably) write

  while (1)
    if (A)
        break;

instead of while (A), but you do what to write

  while (A)
     if (B)
        break;

instead of while (A && B) just because A has a side effect.  && is both
short-circuiting and has a sequence point precisely so that A && B works
in cases like this.

> i = N;
> while(i--)
>   is idiomatic C for counting down.

and while (i-- & other_condition(i)) is idiomatic for counting while
something else is true.  Both rely on starting with i one more than the
top value for which we are interested, but they are both idiomatic to
me.

-- 
Ben.

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


#17189

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2012-02-12 23:35 +0000
Message-ID<0.6547d4d6a4ba3ceb1e00.20120212233514GMT.87ipjb8w25.fsf@bsb.me.uk>
In reply to#17178
ram@zedat.fu-berlin.de (Stefan Ram) writes:

> Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
>>and while (i-- & other_condition(i)) is idiomatic for counting while
>
>   There might be a typo above: »&« possibly was intended to be »&&«.

Yup, thanks.  Fortunately there were loads of other example that had the
&& so I don't think there will be too much confusion.

-- 
Ben.

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


#17141

FromBarry Schwarz <schwarzb@dqel.com>
Date2012-02-11 14:27 -0800
Message-ID<kbqdj7tm91gen8f4pfvpuc31qtv3ij733s@4ax.com>
In reply to#17114
On Sat, 11 Feb 2012 18:41:12 +0100, August Karlstrom
<fusionfile@gmail.com> wrote:

>On 2012-02-10 19:17, peter wrote:
>> Hello C programmers,
>>          I was wondering does anybody knows how or is there
>> a right trim string function available in C?
>
>No, not in the standard library, but it is not hard to implement. 
>Remember that since strings are constant objects you first need to copy 
>the string to a character array.

While a string literal should be treated as if it were const, a string
in general need not be constant in any sense of the word.

-- 
Remove del for email

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


#17174

FromAugust Karlstrom <fusionfile@gmail.com>
Date2012-02-12 14:40 +0100
Message-ID<jh8fg5$b2r$1@dont-email.me>
In reply to#17141
On 2012-02-11 23:27, Barry Schwarz wrote:
> On Sat, 11 Feb 2012 18:41:12 +0100, August Karlstrom
> <fusionfile@gmail.com>  wrote:
>> Remember that since strings are constant objects you first need to copy
>> the string to a character array.
>
> While a string literal should be treated as if it were const, a string
> in general need not be constant in any sense of the word.

Right, in C a string is any sequence of chars ending with the null 
character.


August

[toc] | [prev] | [standalone]


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

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


csiph-web