Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #17069 > unrolled thread
| Started by | peter <pc722@nospam.mail.com.br> |
|---|---|
| First post | 2012-02-10 18:17 +0000 |
| Last post | 2012-02-12 14:40 +0100 |
| Articles | 16 on this page of 56 — 21 participants |
Back to article view | Back to comp.lang.c
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]
| From | Shao Miller <sha0.miller@gmail.com> |
|---|---|
| Date | 2012-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]
| From | Willem <willem@toad.stack.nl> |
|---|---|
| Date | 2012-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]
| From | Willem <willem@toad.stack.nl> |
|---|---|
| Date | 2012-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]
| From | August Karlstrom <fusionfile@gmail.com> |
|---|---|
| Date | 2012-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]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2012-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]
| From | Malcolm McLean <malcolm.mclean5@btinternet.com> |
|---|---|
| Date | 2012-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]
| From | August Karlstrom <fusionfile@gmail.com> |
|---|---|
| Date | 2012-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]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2012-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]
| From | August Karlstrom <fusionfile@gmail.com> |
|---|---|
| Date | 2012-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]
| From | Malcolm McLean <malcolm.mclean5@btinternet.com> |
|---|---|
| Date | 2012-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]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2012-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]
| From | Malcolm McLean <malcolm.mclean5@btinternet.com> |
|---|---|
| Date | 2012-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]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2012-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]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2012-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]
| From | Barry Schwarz <schwarzb@dqel.com> |
|---|---|
| Date | 2012-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]
| From | August Karlstrom <fusionfile@gmail.com> |
|---|---|
| Date | 2012-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