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 20 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 1 of 3  [1] 2 3  Next page →


#17069 — Right trim string function in C

Frompeter <pc722@nospam.mail.com.br>
Date2012-02-10 18:17 +0000
SubjectRight trim string function in C
Message-ID<jh3n08$6hs$1@speranza.aioe.org>
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();

[toc] | [next] | [standalone]


#17071

FromJames Kuyper <jameskuyper@verizon.net>
Date2012-02-10 13:36 -0500
Message-ID<4F3563A4.10302@verizon.net>
In reply to#17069
On 02/10/2012 01:17 PM, 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"?

Sorry, there's no standard library function that does this. If it's
something you need a lot, you should write your own routine - it won't
be hard.

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


#17074

FromDevil with the China Blue Dress <chine.bleu@yahoo.com>
Date2012-02-10 11:00 -0800
Message-ID<chine.bleu-6467A5.11002210022012@news.eternal-september.org>
In reply to#17071
In article <4F3563A4.10302@verizon.net>, James Kuyper <jameskuyper@verizon.net> 
wrote:

> On 02/10/2012 01:17 PM, 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"?
> 
> Sorry, there's no standard library function that does this. If it's
> something you need a lot, you should write your own routine - it won't
> be hard.

Which is basically something like
    n := strlen(s)
    while n>0 and isspace(s[n-1]),
        s[--n] := 0

However an important gotcha is the string has to be writable and all clients of 
the string will see the trimming. If you may want to make a copy of the string 
and modify that.

-- 
My name Indigo Montoya.      |         It's Coraline, not Caroline.
You flamed my father.        |       I'm whoever you want me to be.
Prepare to be spanked.       |  Annoying Usenet one post at a time.
Stop posting that!           |    At least I can stay in character.

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


#17303

From"BartC" <bc@freeuk.com>
Date2012-02-14 12:41 +0000
Message-ID<jhdkqb$g3q$1@dont-email.me>
In reply to#17074
"Devil with the China Blue Dress" <chine.bleu@yahoo.com> wrote in message
news:chine.bleu-6467A5.11002210022012@news.eternal-september.org...

> Which is basically something like
>    n := strlen(s)
>    while n>0 and isspace(s[n-1]),
>        s[--n] := 0
>
> However an important gotcha is the string has to be writable and all
> clients of
> the string will see the trimming. If you may want to make a copy of the
> string
> and modify that.

Alternatively, the function can just calculate what the trimmed portion is,
without doing any of the actual work of constructing a new string; the
caller can do that, if it needs to.

Example prototype:

str:       pointer to char-sequence (need not be right-terminated
           when length is provided)
length:    -1 when unknown, or 0 or more when caller provides the length

return:    length of trimmed portion

When no length info is provided, this needs one pass through the string.
With a length, it's mainly just the trimmed portion that needs to be
scanned.

(Or just forget the length; I'm working with unterminated strings at present 
so find it more natural.)

-- 
Bartc 

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


#17308

From"BartC" <bc@freeuk.com>
Date2012-02-14 14:14 +0000
Message-ID<jhdq9f$dce$1@dont-email.me>
In reply to#17303
"BartC" <bc@freeuk.com> wrote in message news:jhdkqb$g3q$1@dont-email.me...
> "Devil with the China Blue Dress" <chine.bleu@yahoo.com> wrote in message

>> However an important gotcha is the string has to be writable and all
>> clients of
>> the string will see the trimming.

> Example prototype:

Too much editing and the prototype disappeared! It might look like:

int trimstringright(char* str, int length);

(size_t can be used, if an alternative to -1 for the length can be found.)

Here's some code, although not as efficient as it could be when no length is 
provided:

int trimstringright(char* str, int length){
char *p;

if (str==NULL)return 0;
if (length==-1) length=strlen(str);  //being lazy..
if (length==0) return 0;

p=str+length-1;

while (p>=str && *p-- == ' ') --length;

return length;
}

-- 
Bartc 

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


#17343

FromIke Naar <ike@iceland.freeshell.org>
Date2012-02-15 00:03 +0000
Message-ID<slrn3vfsjjltig.1lm.ike@iceland.freeshell.org>
In reply to#17308
On 2012-02-14, BartC <bc@freeuk.com> wrote:
> "BartC" <bc@freeuk.com> wrote in message news:jhdkqb$g3q$1@dont-email.me...
>> "Devil with the China Blue Dress" <chine.bleu@yahoo.com> wrote in message
>
>>> However an important gotcha is the string has to be writable and all
>>> clients of
>>> the string will see the trimming.
>
>> Example prototype:
>
> Too much editing and the prototype disappeared! It might look like:
>
> int trimstringright(char* str, int length);
>
> (size_t can be used, if an alternative to -1 for the length can be found.)
>
> Here's some code, although not as efficient as it could be when no length is 
> provided:
>
> int trimstringright(char* str, int length){
> char *p;
>
> if (str==NULL)return 0;
> if (length==-1) length=strlen(str);  //being lazy..
> if (length==0) return 0;
>
> p=str+length-1;
>
> while (p>=str && *p-- == ' ') --length;
>
> return length;
> }

Consider trimstringright(" ",1);
Just before the while loop, length==1 and p==str.
In the first iteration, the loop condition holds,
and p is decremented and now points outside the string.
In the second iteration, the access to p in "p>=str"
has undefined behaviour.

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


#17347

From"BartC" <bc@freeuk.com>
Date2012-02-15 01:00 +0000
Message-ID<jhf07u$d0q$1@dont-email.me>
In reply to#17343
"Ike Naar" <ike@iceland.freeshell.org> wrote in message 
news:slrn3vfsjjltig.1lm.ike@iceland.freeshell.org...
> On 2012-02-14, BartC <bc@freeuk.com> wrote:
>> "BartC" <bc@freeuk.com> wrote in message 
>> news:jhdkqb$g3q$1@dont-email.me...

[Scanning a string backwards]

>> p=str+length-1;
>>
>> while (p>=str && *p-- == ' ') --length;

> Consider trimstringright(" ",1);
> Just before the while loop, length==1 and p==str.
> In the first iteration, the loop condition holds,
> and p is decremented and now points outside the string.
> In the second iteration, the access to p in "p>=str"
> has undefined behaviour.

OK, let's suppose that on some machine, it is meaningless to point to an 
address before 'str'; why would the problem occur on the next access to p, 
rather than in the p-- operation, or in the >= comparison?

And, on a machine which doesn't have such problems (eg. flat address space, 
str not located at the beginning of that space, and the ability to compare 
pointers even when the memory locations involved do not exist), would it 
still be undefined behaviour?

-- 
Bartc 

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


#17350

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2012-02-15 02:08 +0000
Message-ID<0.ed1b7f41d4cfb03a031f.20120215020820GMT.87vcn8zw4r.fsf@bsb.me.uk>
In reply to#17347
"BartC" <bc@freeuk.com> writes:

> "Ike Naar" <ike@iceland.freeshell.org> wrote in message
> news:slrn3vfsjjltig.1lm.ike@iceland.freeshell.org...
>> On 2012-02-14, BartC <bc@freeuk.com> wrote:
>>> "BartC" <bc@freeuk.com> wrote in message
>>> news:jhdkqb$g3q$1@dont-email.me...
>
> [Scanning a string backwards]
>
>>> p=str+length-1;
>>>
>>> while (p>=str && *p-- == ' ') --length;
>
>> Consider trimstringright(" ",1);
>> Just before the while loop, length==1 and p==str.
>> In the first iteration, the loop condition holds,
>> and p is decremented and now points outside the string.
>> In the second iteration, the access to p in "p>=str"
>> has undefined behaviour.
>
> OK, let's suppose that on some machine, it is meaningless to point to
> an address before 'str'; why would the problem occur on the next
> access to p, rather than in the p-- operation, or in the >=
> comparison?

You are right.  The first (main?) problem is p-- (actually the implied
p-1).  Simply calculating this pointer is undefined.  Referring to p is
also undefined, as is the comparison p>=str, but the root problem is
subtracting one from a pointer equal to str.

[This assumes that str points to the start of an object.  You can't
tell by looking at the code if this true of not, but it's clear from
the purpose of it that it might be, so the code should avoid this
problem.]

> And, on a machine which doesn't have such problems (eg. flat address
> space,

"Flatness" is not enough on its own.  One can imagine some form of bound
checking that actually enforces the rule even when the address space is
flat.

> str not located at the beginning of that space, and the ability
> to compare pointers even when the memory locations involved do not
> exist), would it still be undefined behaviour?

Yes, because in this context, undefined does not mean "goes wrong", it
just means that C does not define what happens.  That does not change
even in the most forgiving environment.  In practise what happens is
that other things step in and define what happens to code like this
where the language specification has nothing more to say.  The compiler,
the machine, the OS all conspire to extend the C standard so that code
such as the above may well have a well-defined meaning.

The trouble is that you loose portability, and the assurances that the
code will work are often simply assumed rather than being explicit.

-- 
Ben.

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


#17363

FromMalcolm McLean <malcolm.mclean5@btinternet.com>
Date2012-02-15 03:08 -0800
Message-ID<404c0142-798d-41f9-977c-40847893584b@d15g2000yqg.googlegroups.com>
In reply to#17347
On Feb 15, 1:00 am, "BartC" <b...@freeuk.com> wrote:
>
> And, on a machine which doesn't have such problems (eg. flat address space,
> str not located at the beginning of that space, and the ability to compare
> pointers even when the memory locations involved do not exist), would it
> still be undefined behaviour?
>
Yes. "It works" is in fact the most dangerous form of undefined
behaviour.
--
Basic Algorithms - learn how to implement floating point arithmetic
http://www.malcolmmclean.site11.com/www

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


#17366

Fromgazelle@shell.xmission.com (Kenny McCormack)
Date2012-02-15 13:00 +0000
Message-ID<jhgaa1$7h7$2@news.xmission.com>
In reply to#17363
In article <404c0142-798d-41f9-977c-40847893584b@d15g2000yqg.googlegroups.com>,
Malcolm McLean  <malcolm.mclean5@btinternet.com> wrote:
>On Feb 15, 1:00 am, "BartC" <b...@freeuk.com> wrote:
>>
>> And, on a machine which doesn't have such problems (eg. flat address space,
>> str not located at the beginning of that space, and the ability to compare
>> pointers even when the memory locations involved do not exist), would it
>> still be undefined behaviour?
>>
>Yes. "It works" is in fact the most dangerous form of undefined
>behaviour.

Hah hah.  Of course, I understand this phrase in the CLC context, but I have
to point out that I think most working code in the real world does, in fact,
have undefined behavior coursing through its veins.  But the PHBs don't care
- as long as it works (*), and the money keeps coming in, they don't care.

(*) Or at least, as is usually the case, "seems to work".

-- 
Modern Christian: Someone who can take time out from
complaining about "welfare mothers popping out babies we
have to feed" to complain about welfare mothers getting
abortions that PREVENT more babies to be raised at public 
expense.

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


#17411

FromKaz Kylheku <kaz@kylheku.com>
Date2012-02-16 00:36 +0000
Message-ID<20120215163101.672@kylheku.com>
In reply to#17366
On 2012-02-15, Kenny McCormack <gazelle@shell.xmission.com> wrote:
> In article <404c0142-798d-41f9-977c-40847893584b@d15g2000yqg.googlegroups.com>,
> Malcolm McLean  <malcolm.mclean5@btinternet.com> wrote:
>>On Feb 15, 1:00 am, "BartC" <b...@freeuk.com> wrote:
>>>
>>> And, on a machine which doesn't have such problems (eg. flat address space,
>>> str not located at the beginning of that space, and the ability to compare
>>> pointers even when the memory locations involved do not exist), would it
>>> still be undefined behaviour?
>>>
>>Yes. "It works" is in fact the most dangerous form of undefined
>>behaviour.
>
> Hah hah.  Of course, I understand this phrase in the CLC context, but I have
> to point out that I think most working code in the real world does, in fact,
> have undefined behavior coursing through its veins.

Simply including a nonstandard header which is not present in the program is
undefined behavior. Calling external functions that are not in ISO C and not
defined in the program is also undefined behavior.

A program that includes <unistd.h> and calls open is undefined according to
ISO C, but may be a well-defined POSIX C program.

This is why obsessing over undefined behavior is silly. Undefined behavior
just means, "you're leaving that province of C programming where ISO C
provides a useful opinion".

It's all just opinions, because at the end of the day, the compiler and library
may do something else, and you still want to ship something.

Only what actually happens in the machine you're programming is "behavior".

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


#17409

FromKaz Kylheku <kaz@kylheku.com>
Date2012-02-16 00:28 +0000
Message-ID<20120215162359.985@kylheku.com>
In reply to#17347
On 2012-02-15, BartC <bc@freeuk.com> wrote:
> And, on a machine which doesn't have such problems (eg. flat address space, 
> str not located at the beginning of that space, and the ability to compare 
> pointers even when the memory locations involved do not exist), would it 
> still be undefined behaviour?

"Undefined behavior" means that the C standard doesn't have an opinion on the
meaning of a construct (a requirement is not imposed).

On the machine that you describe, by golly, the C standard still doesn't
impose a requirement. The document hasn't changed.

On that machine/compiler you may have a behavior that is defined, but that
doesn't come from any requirements in standard C, that is all.

Defined by your tools, not defined by standard C.

(That kind of "defined" works in practice and is often good enough.)

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


#18571

Fromgordonb.7bjv1@burditt.org (Gordon Burditt)
Date2012-03-12 03:27 -0500
Message-ID<8bCdnTtjM5L5LsDSnZ2dnUVZ_rmdnZ2d@posted.internetamerica>
In reply to#17347
>>> p=str+length-1;
>>>
>>> while (p>=str && *p-- == ' ') --length;

> OK, let's suppose that on some machine, it is meaningless to point to an 
> address before 'str'; why would the problem occur on the next access to p, 
> rather than in the p-- operation, or in the >= comparison?

It might occur on p--;.  Some processors (Pentium included, if you
use the right pointer types, which would be associated with large
memory model (48-bit pointers)) will trap if you load an invalid
pointer into a segment register.  Programs that need 48-bit pointers
are *big* programs.  However, this kind of pickiness tends to break
supposedly working software and it will be unpopular with customers.
Also, it isn't necessary to put a pointer into a segment register
just for this and putting a pointer into a segment register is an
expensive operation on a Pentium.  C is not guaranteed to catch
such errors (you might read random crap instead of trapping) and
it is especially not guaranteed to catch such errors as soon as
possible.

> And, on a machine which doesn't have such problems (eg. flat address space, 
> str not located at the beginning of that space, and the ability to compare 
> pointers even when the memory locations involved do not exist), would it 
> still be undefined behaviour?

Regardless of what it *DOES*, it's still undefined behavior:  there
is no wrong behaviour.  One of the most insidious forms of undefined
behavior is "do what I expected" or "do what I expected except under
conditions only likely to happen during a demonstration of the
software to the customer".

Some systems randomize the locations of where things are loaded to
avoid vulnerabilities to things such as buffer-overflow attacks (it
might still crash but not be an exploitable hole for a virus to
take over the computer), so it might actually end up at the beginning
of the space 0.01% of the time.

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


#18575

FromChina Blue Water Navy <chine.bleu@yahoo.com>
Date2012-03-12 03:57 -0800
Message-ID<chine.bleu-2623B5.03573512032012@news.eternal-september.org>
In reply to#18571
> Regardless of what it *DOES*, it's still undefined behavior:  there
> is no wrong behaviour.  One of the most insidious forms of undefined
> behavior is "do what I expected" or "do what I expected except under

The suggested pseudo-code was

    n := strlen(s)
    while n>0 and isspace(s[n-1]),
        s[--n] := 0

where you use an integer subscript instead of a pointer. The integer can go out 
of range as long as it is guarded so the subscript is always in range. If n=0, 
the subscripts s[n-1] and s[--n] would be invalid, but the guard n>0 keeps them 
from being evaluated.

-- 
My name Indigo Montoya.      |    R'lyeh 38o57'6.5''S 102o51'16''E.
You flamed my father.        |       I'm whoever you want me to be.
Prepare to be spanked.       |  Annoying Usenet one post at a time.
Stop posting that!           |    At least I can stay in character.

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


#17320

FromDevil with the China Blue Dress <chine.bleu@yahoo.com>
Date2012-02-14 09:59 -0800
Message-ID<chine.bleu-325583.09595314022012@news.eternal-september.org>
In reply to#17303
In article <jhdkqb$g3q$1@dont-email.me>, "BartC" <bc@freeuk.com> wrote:

> "Devil with the China Blue Dress" <chine.bleu@yahoo.com> wrote in message
> news:chine.bleu-6467A5.11002210022012@news.eternal-september.org...
> 
> > Which is basically something like
> >    n := strlen(s)
> >    while n>0 and isspace(s[n-1]),
> >        s[--n] := 0
> >
> > However an important gotcha is the string has to be writable and all
> > clients of
> > the string will see the trimming. If you may want to make a copy of the
> > string
> > and modify that.
> 
> Alternatively, the function can just calculate what the trimmed portion is,
> without doing any of the actual work of constructing a new string; the
> caller can do that, if it needs to.
> 
> Example prototype:
> 
> str:       pointer to char-sequence (need not be right-terminated
>            when length is provided)
> length:    -1 when unknown, or 0 or more when caller provides the length
> 
> return:    length of trimmed portion
> 
> When no length info is provided, this needs one pass through the string.
> With a length, it's mainly just the trimmed portion that needs to be
> scanned.
> 
> (Or just forget the length; I'm working with unterminated strings at present 
> so find it more natural.)

Or package strings in a struct with the string pointer, string length, and 
allocated size. A zero allocated size means the string is not known to be heap 
based and presumed unmodifiable; a nonzero allocated size means the string is 
allocated on the heap, can be appended to, and can be reallocated to larger and 
smaller sizes.

typedef struct {char *s; int n, m;} VString;
#define vstring(s, n) ((VString){s, n, 0})
    //if n<0, length is strlen(s)

size_t vlen(VString vs) {
    if (!vs.s) return 0;
    if (vs.n<0) return strlen(vs.s);
    return vs.n;
}
char *vstr(VString vs) {
    if (!vs.s) return "";
    return vs.s;
}
char *vcstr(VString vs, bool *copied) {
    if (!vs.s) {
        if (copied) *copied = false; return "";
    }else if (vs.n<0) {
        if (copied) *copied = false; return vs.s;
    }else if (vs.m>vs.n && vs.s[vs.n]==0) {
        if (copied) *copied = false; return vs.s;
    }else {
        if (copied) *copied = true;
        char *d = malloc(vs.n+1); memcpy(d, vs.s, vs.n); d[vs.n] = 0;
        return d;
    }
}

int vfirst(VString vs) {
    if (!vs.s) return -1;
    if (vs.n<0) vs.n = strlen(vs.s);
    return vs.n==0 ? -1 : ((unsigned char*)(vs.s))[0];
}
int vlast(VString vs) {
    if (!vs.s) return -1;
    if (vs.n<0) vs.n = strlen(vs.s);
    return vs.n==0 ? -1 : ((unsigned char*)(vs.s))[vs.n-1];
}
VString vrest(VString vs) {
    if (!vs.s) return vs;
    if (vs.n<0) vs.n = strlen(vs.s);
    return vstring(vs.s+1, vs.n-1);
}
VString vfront(VString vs) {
    if (!vs.s) return vs;
    if (vs.n<0) vs.n = strlen(vs.s);
    return (VString){vs.s, vs.n-1, vs.m};
}
VString vtrim(VString vs) {
    if (!vs.s) return vs;
    if (vs.n<0) vs.n = strlen(vs.s);
    while (vfirst(vs)>=0 && !isspace(vfirst(vs))) vs = vrest(vs);
    while (vlast(vs)>=0 && !isspace(vlast(vs))) vs = vfront(vs);
    return vs;
}
VString vappend(VString vs, char c) {
    if (!vs.s) {
        vs = (VString){malloc(1), 0, 1); vs.s[0] = 0;
    }
    if (vs.n<0) vs.n = strlen(vs.s);
    if (vs.m==0) {
        char *d = malloc(2*vs.n); strcpy(d, vs.s);
        vs = (VString){d, vs.n, 2*vs.n};
    }
    if (vs.n+1==vs.m) {
        vs.m *= 2;
        vs = (VString){realloc(vs.s, vs.m), vs.n, vs.m};
    }
    vs.s[vs.n++] = c; vs.s[vs.n] = 0;
}

-- 
My name Indigo Montoya.      |         It's Coraline, not Caroline.
You flamed my father.        |       I'm whoever you want me to be.
Prepare to be spanked.       |  Annoying Usenet one post at a time.
Stop posting that!           |    At least I can stay in character.

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


#17304

FromKaz Kylheku <kaz@kylheku.com>
Date2012-02-14 12:56 +0000
Message-ID<20120214045001.926@kylheku.com>
In reply to#17074
On 2012-02-10, Devil with the China Blue Dress <chine.bleu@yahoo.com> wrote:
> Which is basically something like
>     n := strlen(s)
>     while n>0 and isspace(s[n-1]),
>         s[--n] := 0
>
> However an important gotcha is the string has to be writable and all clients of 
> the string will see the trimming. If you may want to make a copy of the string 
> and modify that.

Oh yeah, you wouldn't want to spoil the functional purity of C programming with
an underhanded destructive hack, such as trimming a string in place!

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


#17317

FromDevil with the China Blue Dress <chine.bleu@yahoo.com>
Date2012-02-14 09:17 -0800
Message-ID<chine.bleu-F484D9.09173614022012@news.eternal-september.org>
In reply to#17304
In article <20120214045001.926@kylheku.com>, Kaz Kylheku <kaz@kylheku.com> 
wrote:

> On 2012-02-10, Devil with the China Blue Dress <chine.bleu@yahoo.com> wrote:
> > Which is basically something like
> >     n := strlen(s)
> >     while n>0 and isspace(s[n-1]),
> >         s[--n] := 0
> >
> > However an important gotcha is the string has to be writable and all 
> > clients of 
> > the string will see the trimming. If you may want to make a copy of the 
> > string 
> > and modify that.
> 
> Oh yeah, you wouldn't want to spoil the functional purity of C programming 
> with
> an underhanded destructive hack, such as trimming a string in place!

Since I use the Boehms garbage collector, I would just duplicate the string in 
the function, letting me use pure functions. Those who wish to preserve the 
purity of C will need alternative schemes to track string ownership and 
modifiability.

-- 
My name Indigo Montoya.      |         It's Coraline, not Caroline.
You flamed my father.        |       I'm whoever you want me to be.
Prepare to be spanked.       |  Annoying Usenet one post at a time.
Stop posting that!           |    At least I can stay in character.

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


#17325

FromMalcolm McLean <malcolm.mclean5@btinternet.com>
Date2012-02-14 10:10 -0800
Message-ID<89875620-1ab7-4146-b623-c46439c6fd48@p12g2000yqe.googlegroups.com>
In reply to#17304
On Feb 14, 12:56 pm, Kaz Kylheku <k...@kylheku.com> wrote:
>
> Oh yeah, you wouldn't want to spoil the functional purity of C programming with
> an underhanded destructive hack, such as trimming a string in place!
>
I do sometimes use my own little library that accepts const string and
returns the result in an allocated string. But I find the advantage is
small.
MPI tutorial
http://www.malcolmmclean.site1.com/www

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


#17076

FromBarry Schwarz <schwarzb@dqel.com>
Date2012-02-10 11:30 -0800
Message-ID<2qqaj791gt4d2fjgtlmds1asoqll9bhq0g@4ax.com>
In reply to#17069
On 10 Feb 2012 18:59:36 GMT, ram@zedat.fu-berlin.de (Stefan Ram)
wrote:

>peter <pc722@nospam.mail.com.br> writes:
>>char *str = "Hello Dolly     \0";
>(...)
>>In PYTHON there is a useful function for this: str.rstrip();
>
>  Untested and assuming that the string is in a mutable buffer:
>
>#include <ctype.h>
>#include <string.h>
>
>void rstrip( char * const string )
>{ char * last = string + strlen( string )- 1; 
>  while( last >= string && isspace( last ))*last-- = 0; }

If the string consists entirely of blanks, is it undefined behavior
for last to end up pointing before the start of the string?  This
value is not dereferenced but it is used one last time in the first
relational expression.

Why have all the solutions so far changed all the trailing blanks to
nuls?  Wouldn't it be sufficient and more efficient to change only the
first one?

  while( last > string && isspace( last-- ));
  *++last = 0; }

which has the "advantage" of changing a string of all blanks to one
with a single blank instead of the empty string.

-- 
Remove del for email

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


#17077

FromJames Kuyper <jameskuyper@verizon.net>
Date2012-02-10 14:45 -0500
Message-ID<4F3573DB.60505@verizon.net>
In reply to#17076
On 02/10/2012 02:30 PM, Barry Schwarz wrote:
> On 10 Feb 2012 18:59:36 GMT, ram@zedat.fu-berlin.de (Stefan Ram)
> wrote:
> 
>> peter <pc722@nospam.mail.com.br> writes:
[snipage restored:]
>>>         Is there a right trim function that will remove the
>>> trailing spaces and make *str look like "Hello Dolly\0"?
...
> Why have all the solutions so far changed all the trailing blanks to
> nuls? ...

Because that's what the OP requested (see above).

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


Page 1 of 3  [1] 2 3  Next page →

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


csiph-web