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


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

strsup - supplementary string functions

Started byMalcolm McLean <malcolm.mclean5@btinternet.com>
First post2013-01-22 10:14 -0800
Last post2013-02-03 14:33 -0800
Articles 20 on this page of 21 — 14 participants

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


Contents

  strsup - supplementary string functions Malcolm McLean <malcolm.mclean5@btinternet.com> - 2013-01-22 10:14 -0800
    Re: strsup - supplementary string functions Keith Thompson <kst-u@mib.org> - 2013-01-22 11:23 -0800
      Re: strsup - supplementary string functions James Kuyper <jameskuyper@verizon.net> - 2013-01-22 14:34 -0500
        Re: strsup - supplementary string functions Keith Thompson <kst-u@mib.org> - 2013-01-22 11:44 -0800
    Re: strsup - supplementary string functions Johann Klammer <klammerj@NOSPAM.a1.net> - 2013-01-22 22:57 +0100
    Re: strsup - supplementary string functions Jorgen Grahn <grahn+nntp@snipabacken.se> - 2013-01-23 21:13 +0000
      Re: strsup - supplementary string functions Ben Bacarisse <ben.usenet@bsb.me.uk> - 2013-01-23 23:08 +0000
    Re: strsup - supplementary string functions Bjorn Augestad <bjorn.augestad@gmail.com> - 2013-01-23 22:54 +0100
    Re: strsup - supplementary string functions Dr Nick <nospam-4@temporary-address.org.uk> - 2013-01-24 07:44 +0000
      Re: strsup - supplementary string functions Malcolm McLean <malcolm.mclean5@btinternet.com> - 2013-01-24 01:12 -0800
        Re: strsup - supplementary string functions "BartC" <bc@freeuk.com> - 2013-01-25 18:27 +0000
          Re: strsup - supplementary string functions Malcolm McLean <malcolm.mclean5@btinternet.com> - 2013-01-28 01:24 -0800
    Re: strsup - supplementary string functions John McCue <jmccue@jmcbsd0.hsd1.ma.comcast.net> - 2013-01-24 22:28 +0000
    Re: strsup - supplementary string functions JohnF <john@please.see.sig.for.email.com> - 2013-01-25 10:57 +0000
      Re: strsup - supplementary string functions 88888 Dihedral <dihedral88888@googlemail.com> - 2013-01-25 12:45 -0800
    Re: strsup - supplementary string functions ssmitch@gmail.com - 2013-01-29 08:17 -0800
      Re: strsup - supplementary string functions Malcolm McLean <malcolm.mclean5@btinternet.com> - 2013-01-29 09:57 -0800
      Re: strsup - supplementary string functions Ben Bacarisse <ben.usenet@bsb.me.uk> - 2013-01-30 03:46 +0000
        Re: strsup - supplementary string functions Tim Rentsch <txr@alumni.caltech.edu> - 2013-01-31 14:50 -0800
          Re: strsup - supplementary string functions Ben Bacarisse <ben.usenet@bsb.me.uk> - 2013-02-02 02:45 +0000
            Re: strsup - supplementary string functions Tim Rentsch <txr@alumni.caltech.edu> - 2013-02-03 14:33 -0800

Page 1 of 2  [1] 2  Next page →


#30512 — strsup - supplementary string functions

FromMalcolm McLean <malcolm.mclean5@btinternet.com>
Date2013-01-22 10:14 -0800
Subjectstrsup - supplementary string functions
Message-ID<2dc6b2f9-f029-43a0-b7e6-6258548a1a2f@googlegroups.com>
I'm putting together a little library of supplementary string functions,
strsup.c.

The functions are intended to be fairly short, and to operate on char *s.
They should ideally be implementable as a single function which can be snipped
and pasted.

Unlike the string.h functions they can depend on malloc().

The obvious first function is strdup().

I've also got

strcount - count the instances of character ch in str.
trim - remove leadign and trailing whitespace from a string
singlespace - repalce all runs of whitespace in a string with a single 
space character.
split - return an array of fields, split on a delimiter character.
compnumeric - compare two strings with embedded numbers.
replace - replace all substrings with new passed string.

Any ideas for more?
 

[toc] | [next] | [standalone]


#30515

FromKeith Thompson <kst-u@mib.org>
Date2013-01-22 11:23 -0800
Message-ID<lnobgh3tud.fsf@nuthaus.mib.org>
In reply to#30512
Malcolm McLean <malcolm.mclean5@btinternet.com> writes:
> I'm putting together a little library of supplementary string functions,
> strsup.c.
>
> The functions are intended to be fairly short, and to operate on char *s.
> They should ideally be implementable as a single function which can be snipped
> and pasted.
>
> Unlike the string.h functions they can depend on malloc().
>
> The obvious first function is strdup().
>
> I've also got
>
> strcount - count the instances of character ch in str.
> trim - remove leadign and trailing whitespace from a string
> singlespace - repalce all runs of whitespace in a string with a single 
> space character.
> split - return an array of fields, split on a delimiter character.
> compnumeric - compare two strings with embedded numbers.
> replace - replace all substrings with new passed string.

Just one comment: the name "strcount" is reserved.  And the other names
could easily conflict with existing identifiers in user code.

You might consider inventing a consistent naming scheme for your
functions.

If the purpose is to copy-and-paste the definitions, the user can change
the name easily enough, but if they're going to be part of a library
(which would make sense), then naming becomes more important.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

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


#30516

FromJames Kuyper <jameskuyper@verizon.net>
Date2013-01-22 14:34 -0500
Message-ID<50FEE9AE.1030406@verizon.net>
In reply to#30515
On 01/22/2013 02:23 PM, Keith Thompson wrote:
> -- 
> Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
> Working, but not speaking, for JetHead Development, Inc.

I just noticed that you've dropped your "Will write code for food" sig.
Congratulations, and good luck!

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


#30517

FromKeith Thompson <kst-u@mib.org>
Date2013-01-22 11:44 -0800
Message-ID<lnk3r53sv2.fsf@nuthaus.mib.org>
In reply to#30516
James Kuyper <jameskuyper@verizon.net> writes:
> On 01/22/2013 02:23 PM, Keith Thompson wrote:
>> -- 
>> Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
>> Working, but not speaking, for JetHead Development, Inc.
>
> I just noticed that you've dropped your "Will write code for food" sig.
> Congratulations, and good luck!

Thanks!

I'm actually doing C programming, something I haven't done
professionally in quite a while.  (Or, How I Learned To Stop Worrying
And Love Undefined Behavior.)

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

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


#30542

FromJohann Klammer <klammerj@NOSPAM.a1.net>
Date2013-01-22 22:57 +0100
Message-ID<50ff0b4d$0$22866$91cee783@newsreader03.highway.telekom.at>
In reply to#30512
Malcolm McLean wrote:
>
> Any ideas for more?
>
I've been using those...

///replace non ascii printable chars with spaces
void utlAsciiSanitize(char *p);
/**
  *\brief concat+realloc
  *
  *Will fail if called with str_p, size_p or str2 equal NULL or if
  *allocation fails.
  *
  *\param str_p points to a char pointer pointing to a c string.
  *May point to a char * holding NULL when calling, in which case
  *memory will be allocated to hold the string to append.
  *space may be reallocated for the string.
  *\param size_p points to an unsigned holding allocated size.
  *May be modified.
  *\param str2 string to append. Must be NUL terminated.
  *Must not be NULL.
  *\returns 1 on error, 0 on success.
  */
int utlSmartCat(char **str_p, unsigned *size_p, char *str2);
///concat+realloc unterminated second string. _Always_ uses size2 bytes 
from str2.
int utlSmartCatUt(char **str_p, unsigned *size_p, char *str2, unsigned 
size2);
///realloc to strlen+1 (not actually necessary)
int utlSmartCatDone(char **str_p);

///smart cat for general arrays
int utlSmartMemmove(uint8_t **str_p, unsigned *size_p,
unsigned *alloc_p, uint8_t *str2, unsigned size2);

extern char * UTL_UNDEF;
/**
  *\brief string lookup
  *
  *look up string at idx
  *\param idx index to look up. Must be some integer type.
  *\param tbl _has_ to be of type char *tbl[]
  *\return a char * from tbl or STRU_UNDEF if out of bounds.
  *STRU_UNDEF is a printable char *.
  */
#define utlGetStr(tbl,idx) 
(((idx)>=(sizeof(tbl)/sizeof(char*)))?UTL_UNDEF:tbl[(idx)])

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


#30579

FromJorgen Grahn <grahn+nntp@snipabacken.se>
Date2013-01-23 21:13 +0000
Message-ID<slrnkg0kjj.ah7.grahn+nntp@frailea.sa.invalid>
In reply to#30512
On Tue, 2013-01-22, Malcolm McLean wrote:
> I'm putting together a little library of supplementary string functions,
> strsup.c.
>
> The functions are intended to be fairly short, and to operate on char *s.
> They should ideally be implementable as a single function which can be snipped
> and pasted.
>
> Unlike the string.h functions they can depend on malloc().
>
> The obvious first function is strdup().
>
> I've also got
>
> strcount - count the instances of character ch in str.
> trim - remove leadign and trailing whitespace from a string

trim_right() might often be what people want, and it has nicer
semantics.  Provide that one too.

> singlespace - repalce all runs of whitespace in a string with a single 
> space character.
> split - return an array of fields, split on a delimiter character.

There are a number of variations on that theme, like:
- split at most in N places
- split on whitespace (one or more SP, TAB etc)
- split and trim whitespace
- ...

I usually find that the simplest kind of split() leaves too much work
for me to do, so I've implemented some of those.  On the other hand,
I also use Perl and that may influence my percieved needs ...

> Any ideas for more?

- an is_empty(), so I don't have to see a myriad variations like
  if(!s[0]); if(!*s); if(s[0]==0); if(s[0]=='0'); if(!strlen(s)) ...

- an equality test so I don't have to see all the variations on
  strcmp() ...

/Jorgen

-- 
  // Jorgen Grahn <grahn@  Oo  o.   .     .
\X/     snipabacken.se>   O  o   .

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


#30585

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2013-01-23 23:08 +0000
Message-ID<0.be52341e9774ebaa47d0.20130123230831GMT.87d2wv1or4.fsf@bsb.me.uk>
In reply to#30579
Jorgen Grahn <grahn+nntp@snipabacken.se> writes:

> On Tue, 2013-01-22, Malcolm McLean wrote:
<snip>
>> trim - remove leadign and trailing whitespace from a string
>
> trim_right() might often be what people want, and it has nicer
> semantics.  Provide that one too.

A small point: when considering strings that are likely to contain text
the meaning of left and right is ambiguous.  Even if this library is
currently all about ASCII strings (I don't recall) consistency with
future names might be worth considering.  Terms like start and end (as
well as leading and trailing) are neutral in this sense.

<snip>
-- 
Ben.

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


#30580

FromBjorn Augestad <bjorn.augestad@gmail.com>
Date2013-01-23 22:54 +0100
Message-ID<kdpm7e$dlj$1@speranza.aioe.org>
In reply to#30512
Den 22.01.2013 19:14, skrev Malcolm McLean:
> I'm putting together a little library of supplementary string functions,
> strsup.c.
>
> The functions are intended to be fairly short, and to operate on char *s.
> They should ideally be implementable as a single function which can be snipped
> and pasted.
>
> Unlike the string.h functions they can depend on malloc().
>
> The obvious first function is strdup().
>
> I've also got
>
> strcount - count the instances of character ch in str.
> trim - remove leadign and trailing whitespace from a string
> singlespace - repalce all runs of whitespace in a string with a single
> space character.
> split - return an array of fields, split on a delimiter character.
> compnumeric - compare two strings with embedded numbers.
> replace - replace all substrings with new passed string.
>
> Any ideas for more?

You may find some ideas here ;-)

http://libclc.cvs.sourceforge.net/viewvc/libclc/libclc/src/clc_string.h?view=markup

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


#30605

FromDr Nick <nospam-4@temporary-address.org.uk>
Date2013-01-24 07:44 +0000
Message-ID<878v7jdnzj.fsf@temporary-address.org.uk>
In reply to#30512
Malcolm McLean <malcolm.mclean5@btinternet.com> writes:

> I'm putting together a little library of supplementary string
> functions,
> strsup.c.
>
> The functions are intended to be fairly short, and to operate on char
> *s.
> They should ideally be implementable as a single function which can be
> snipped
> and pasted.
>
> Unlike the string.h functions they can depend on malloc().
>
> The obvious first function is strdup().
>
> I've also got
>
> strcount - count the instances of character ch in str.
> trim - remove leadign and trailing whitespace from a string
> singlespace - repalce all runs of whitespace in a string with a single
> space character.
> split - return an array of fields, split on a delimiter character.
> compnumeric - compare two strings with embedded numbers.
> replace - replace all substrings with new passed string.
>
> Any ideas for more?

Unless you change your mind and create (yet another, we've all done it)
structure based string type, here's a suggestion: have a very clear
convention in the naming as to which of your functions return the
original string, perhaps modified (convert case, trim the
right-hand-end) and which return a new string.  In fact, think hard
about this all over (should replace always create a new string, create a
new string when lengthening but not shortening, or realloc when
necessary?).

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


#30608

FromMalcolm McLean <malcolm.mclean5@btinternet.com>
Date2013-01-24 01:12 -0800
Message-ID<9a56dea9-ecaa-495d-ab28-4366bf38c8bc@googlegroups.com>
In reply to#30605
On Thursday, January 24, 2013 7:44:16 AM UTC, Dr Nick wrote:
> Malcolm McLean <malcolm.mclean5@btinternet.com> writes:
> 
> 
> Unless you change your mind and create (yet another, we've all done it)
> structure based string type, here's a suggestion: have a very clear
> convention in the naming as to which of your functions return the
> original string, perhaps modified (convert case, trim the
> right-hand-end) and which return a new string.  In fact, think hard
> about this all over (should replace always create a new string, create a
> new string when lengthening but not shortening, or realloc when
> necessary?).
>
The function will all take nul-terminated strings passed as char *s or 
const char *s. The idea is to write functions that should have been in 
string.h but weren't, either because of perceived need, or because string.h
isn't allowed to depend on malloc.

I think it's probably best to return a malloced char * where the return may be larger than the input. Either way is a burden on the caller, malloc has to be tested for null and freed, buffers have to be calculated. But the pass buffer _ length method has points in its favour also. Resolving that issue was one reason for starting this thread.

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


#30641

From"BartC" <bc@freeuk.com>
Date2013-01-25 18:27 +0000
Message-ID<zaAMs.26275$LO7.17163@fx02.fr7>
In reply to#30608
"Malcolm McLean" <malcolm.mclean5@btinternet.com> wrote in message 
news:9a56dea9-ecaa-495d-ab28-4366bf38c8bc@googlegroups.com...
> On Thursday, January 24, 2013 7:44:16 AM UTC, Dr Nick wrote:

>> Unless you change your mind and create (yet another, we've all done it)
>> structure based string type, here's a suggestion: have a very clear
>> convention in the naming as to which of your functions return the
>> original string, perhaps modified (convert case, trim the
>> right-hand-end) and which return a new string.  In fact, think hard
>> about this all over (should replace always create a new string, create a
>> new string when lengthening but not shortening, or realloc when
>> necessary?).
>>
> The function will all take nul-terminated strings passed as char *s or
> const char *s. The idea is to write functions that should have been in
> string.h but weren't, either because of perceived need, or because 
> string.h
> isn't allowed to depend on malloc.
>
> I think it's probably best to return a malloced char * where the return 
> may be larger than the input.

How will the caller know that? And in the case of a trim function, the 
result will never be bigger than the input, but the output may need to be 
stored elsewhere because of the need to zero-terminate a sub-string of the 
input.

As was mentioned, there are just too many ways of dealing with such 
functions: results can be in-place, in a caller-supplied destination, or in 
allocated memory.

Sometimes also, the caller has useful length information for a string, but 
the standard library doesn't often have no way to impart that information to 
the function; that would be handy to be able to do.

For ideas about new string functions, I mainly use the following:

o Convert a string to upper/lower case (some Cs will have this already). I 
also allow just the first N characters to be modified.

o Return the leftmost or rightmost N characters. When N is negative, then 
all *except* the abs(N) rightmost or leftmost characters are returned. When 
N is longer than the string, then it's padded with spaces, or a 
caller-supplied fill character (or string). (Some of this can be done, with 
a bit more trouble, with sprintf().)

o Split or join strings as I  think you've already mentioned.

o Several functions to deal with filespecs:  extract a path, filename, 
basefile, or extension; or to change or add an extension to a filespec.

-- 
Bartc 

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


#30703

FromMalcolm McLean <malcolm.mclean5@btinternet.com>
Date2013-01-28 01:24 -0800
Message-ID<2dbbc7ad-8048-44b6-b1cd-9033356000e7@googlegroups.com>
In reply to#30641
On Friday, January 25, 2013 6:27:16 PM UTC, Bart wrote:
> "Malcolm McLean" <malcolm.mclean5@btinternet.com> wrote in message 
> 
> 
> As was mentioned, there are just too many ways of dealing with such 
> functions: results can be in-place, in a caller-supplied destination, or in 
> allocated memory.
> 
That's one big issue.

trim() could be reasonably an in-place trim function, one that took a const
char * and a buffer (with length supplied or not supplied), or return an
 allocated pointer.
I'd say the first option is best because of the way the function is likely 
to be used. No-one is going to want to pass it a string literal, and only
rarely will you want both a trimmed string and the original retained.
But with replace() you can't easily calculate the output size before calling
it, and it can't be in-place as it's as likely to expand as to shrink the
buffer.

--
Visit Malcolm's website
http://www.malcolmmclean.site11.com

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


#30622

FromJohn McCue <jmccue@jmcbsd0.hsd1.ma.comcast.net>
Date2013-01-24 22:28 +0000
Message-ID<kdscip$18j$1@dont-email.me>
In reply to#30512
Malcolm McLean <malcolm.mclean5@btinternet.com> wrote:
> I'm putting together a little library of supplementary string functions,
> strsup.c.
> 
> The functions are intended to be fairly short, and to operate on char *s.
<snip>
> 
> Any ideas for more?
> 

maybe one which would changed 2 or more spaces to 1 space in
a string.

John

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


#30629

FromJohnF <john@please.see.sig.for.email.com>
Date2013-01-25 10:57 +0000
Message-ID<kdtoen$n4p$1@reader1.panix.com>
In reply to#30512
Malcolm McLean <malcolm.mclean5@btinternet.com> wrote:
> I'm putting together a little library of supplementary string functions,
> strsup.c.
> 
> The functions are intended to be fairly short, and to operate on char *s.
> They should ideally be implementable as a single function which can be
> snipped and pasted.
> 
> Unlike the string.h functions they can depend on malloc().
> 
> The obvious first function is strdup().
> 
> I've also got
> 
> strcount - count the instances of character ch in str.
> trim - remove leadign and trailing whitespace from a string
> singlespace - repalce all runs of whitespace in a string with a single 
> space character.
> split - return an array of fields, split on a delimiter character.
> compnumeric - compare two strings with embedded numbers.
> replace - replace all substrings with new passed string.
> 
> Any ideas for more?

Some might be implemented as macros, especially the snipped-and-pasted
variety. Several snipped-and-pasted examples from my programs are below.
Some do little more than arg-checking, e.g., to avoid segfaulting if
used with a NULL ptr.
  Want about ten zillion other ideas (some arguably a bit over-the-top)?
Look at the VMS documentation about lexical string functions in DCL
(DEC's shell DCL="digital command language"),
  openvms.compaq.com/doc/73final/6489/6489pro_047.html#66_manipulatingstrings

/* ---
 * macro to skip whitespace
 * ------------------------ */
#define WHITESPACE  " \t\n\r\f\v"       /* skipped whitespace chars */
#define skipwhite(thisstr)  if ( (thisstr) != NULL ) \
        thisstr += strspn(thisstr,WHITESPACE)
/* ---
 * macros to check if a string is empty
 * ------------------------------------ */
#define isempty(s)  ((s)==NULL?1:(*(s)=='\000'?1:0))
/* ---
 * macro to strip leading and trailing whitespace
 * ---------------------------------------------- */
#define trimwhite(thisstr) if ( (thisstr) != NULL ) { \
        int thislen = strlen(thisstr); \
        while ( --thislen >= 0 ) \
          if ( isthischar((thisstr)[thislen],WHITESPACE) ) \
            (thisstr)[thislen] = '\000'; \
          else break; \
        if ( (thislen = strspn((thisstr),WHITESPACE)) > 0 ) \
          {strsqueeze((thisstr),thislen);} } else /*user adds ;*/
/* ---
 * macro to remove all 'c' chars from s
 * ------------------------------------ */
#define compress(s,c) if(!isempty(s))   /* remove embedded c's from s */ \
        { char *p; while((p=strchr((s),(c)))!=NULL) {strsqueeze(p,1);} } else
/* ---
 * macro to strcpy(s,s+n) using memmove() (also works for negative n)
 * ------------------------------------------------------------------ */
#define strsqueeze(s,n) if((n)!=0) { if(!isempty((s))) { \
        int thislen3=strlen(s); \
        if ((n) >= thislen3) *(s) = '\000'; \
        else memmove((s),((s)+(n)),(1+thislen3-(n))); }} else /*user adds ;*/
/* ---
 * macro to strncpy() n bytes and make sure it's null-terminated
 * ------------------------------------------------------------- */
#define strninit(target,source,n) \
        if( (target)!=NULL && (n)>=0 ) { \
          char *thissource = (source); \
          (target)[0] = '\000'; \
          if ( (n)>0 && thissource!=NULL ) { \
            strncpy((target),thissource,(n)); \
            (target)[(n)] = '\000'; } }
/* ---
 * macro to check for thischar inthisstr
 * ------------------------------------- */
#define isthischar(thischar,inthisstr) \
        ( (thischar)!='\000' && *(inthisstr)!='\000' \
        && strchr(inthisstr,(thischar))!=(char *)NULL )
/* ---
 * macro for last char of a string
 * ------------------------------- */
#define lastchar(s) (isempty(s)?'\000':*((s)+(strlen(s)-1)))

-- 
John Forkosh  ( mailto:  j@f.com  where j=john and f=forkosh )

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


#30645

From88888 Dihedral <dihedral88888@googlemail.com>
Date2013-01-25 12:45 -0800
Message-ID<1893f9fc-123a-45a8-b7c4-dc88e878ea9a@googlegroups.com>
In reply to#30629
在 2013年1月25日星期五UTC+8下午6时57分27秒,JohnF写道:
> Malcolm McLean <malcolm.mclean5@btinternet.com> wrote:
> 
> > I'm putting together a little library of supplementary string functions,
> 
> > strsup.c.
> 
> > 
> 
> > The functions are intended to be fairly short, and to operate on char *s.
> 
> > They should ideally be implementable as a single function which can be
> 
> > snipped and pasted.
> 
> > 
> 
> > Unlike the string.h functions they can depend on malloc().
> 
> > 
> 
> > The obvious first function is strdup().
> 
> > 
> 
> > I've also got
> 
> > 
> 
> > strcount - count the instances of character ch in str.
> 
> > trim - remove leadign and trailing whitespace from a string
> 
> > singlespace - repalce all runs of whitespace in a string with a single 
> 
> > space character.
> 
> > split - return an array of fields, split on a delimiter character.
> 
> > compnumeric - compare two strings with embedded numbers.
> 
> > replace - replace all substrings with new passed string.
> 
> > 
> 
> > Any ideas for more?
> 
> 
> 
> Some might be implemented as macros, especially the snipped-and-pasted
> 
> variety. Several snipped-and-pasted examples from my programs are below.
> 
> Some do little more than arg-checking, e.g., to avoid segfaulting if
> 
> used with a NULL ptr.
> 
>   Want about ten zillion other ideas (some arguably a bit over-the-top)?
> 
> Look at the VMS documentation about lexical string functions in DCL
> 
> (DEC's shell DCL="digital command language"),
> 
>   openvms.compaq.com/doc/73final/6489/6489pro_047.html#66_manipulatingstrings
> 
> 
> 
> /* ---
> 
>  * macro to skip whitespace
> 
>  * ------------------------ */
> 
> #define WHITESPACE  " \t\n\r\f\v"       /* skipped whitespace chars */
> 
> #define skipwhite(thisstr)  if ( (thisstr) != NULL ) \
> 
>         thisstr += strspn(thisstr,WHITESPACE)
> 
> /* ---
> 
>  * macros to check if a string is empty
> 
>  * ------------------------------------ */
> 
> #define isempty(s)  ((s)==NULL?1:(*(s)=='\000'?1:0))
> 
> /* ---
>
I have to say one subtle point about
the type  char *str=NULL in C.

str=NULL; //  not even allocated 

char str2[10]; //10 bytes alloacted 
str2[0]='\0' ;  // string length is zero

// But I work out my own string library before 
// by my own format to deal with the BIG5 encoding.
 
>  * macro to strip leading and trailing whitespace
> 
>  * ---------------------------------------------- */
> 
> #define trimwhite(thisstr) if ( (thisstr) != NULL ) { \
> 
>         int thislen = strlen(thisstr); \
> 
>         while ( --thislen >= 0 ) \
> 
>           if ( isthischar((thisstr)[thislen],WHITESPACE) ) \
> 
>             (thisstr)[thislen] = '\000'; \
> 
>           else break; \
> 
>         if ( (thislen = strspn((thisstr),WHITESPACE)) > 0 ) \
> 
>           {strsqueeze((thisstr),thislen);} } else /*user adds ;*/
> 
> /* ---
> 
>  * macro to remove all 'c' chars from s
> 
>  * ------------------------------------ */
> 
> #define compress(s,c) if(!isempty(s))   /* remove embedded c's from s */ \
> 
>         { char *p; while((p=strchr((s),(c)))!=NULL) {strsqueeze(p,1);} } else
> 
> /* ---
> 
>  * macro to strcpy(s,s+n) using memmove() (also works for negative n)
> 
>  * ------------------------------------------------------------------ */
> 
> #define strsqueeze(s,n) if((n)!=0) { if(!isempty((s))) { \
> 
>         int thislen3=strlen(s); \
> 
>         if ((n) >= thislen3) *(s) = '\000'; \
> 
>         else memmove((s),((s)+(n)),(1+thislen3-(n))); }} else /*user adds ;*/
> 
> /* ---
> 
>  * macro to strncpy() n bytes and make sure it's null-terminated
> 
>  * ------------------------------------------------------------- */
> 
> #define strninit(target,source,n) \
> 
>         if( (target)!=NULL && (n)>=0 ) { \
> 
>           char *thissource = (source); \
> 
>           (target)[0] = '\000'; \
> 
>           if ( (n)>0 && thissource!=NULL ) { \
> 
>             strncpy((target),thissource,(n)); \
> 
>             (target)[(n)] = '\000'; } }
> 
> /* ---
> 
>  * macro to check for thischar inthisstr
> 
>  * ------------------------------------- */
> 
> #define isthischar(thischar,inthisstr) \
> 
>         ( (thischar)!='\000' && *(inthisstr)!='\000' \
> 
>         && strchr(inthisstr,(thischar))!=(char *)NULL )
> 
> /* ---
> 
>  * macro for last char of a string
> 
>  * ------------------------------- */
> 
> #define lastchar(s) (isempty(s)?'\000':*((s)+(strlen(s)-1)))
> 
> 
> 
> -- 
> 
> John Forkosh  ( mailto:  j@f.com  where j=john and f=forkosh )

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


#30737

Fromssmitch@gmail.com
Date2013-01-29 08:17 -0800
Message-ID<fc0bd09d-1128-4604-a3ed-aa482f772879@googlegroups.com>
In reply to#30512
On Tuesday, January 22, 2013 1:14:18 PM UTC-5, Malcolm McLean wrote:
> I'm putting together a little library of supplementary string functions, strsup.c. The functions are intended to be fairly short, and to operate on char *s. They should ideally be implementable as a single function which can be snipped and pasted. Unlike the string.h functions they can depend on malloc(). The obvious first function is strdup(). I've also got strcount - count the instances of character ch in str. trim - remove leadign and trailing whitespace from a string singlespace - repalce all runs of whitespace in a string with a single space character. split - return an array of fields, split on a delimiter character. compnumeric - compare two strings with embedded numbers. replace - replace all substrings with new passed string. Any ideas for more?

Besides the obvious candidates, I've also found useful on a number of occasions a function to strip unwanted characters (such as commas or dollar signs in numeric values) from a string before further processing.  My own version is simply called strip(), but for a library you would probably want to rename it:

/*
*  remove unwanted characters from string
*
*  call as strip(char *str, *unwanted)
*
*  where "str" is the string to process and "unwanted" is a null-
*  terminated string containing the characters to be stripped.
*
*  returns pointer to modified string
*/

char *strip(char *str, char *unwanted) {
   char *cp, *savptr;
   savptr = str;
   cp = str - 1;
   while (*++cp = *str++)
	   if (strchr(unwanted, *cp) != NULL)
		 --cp;
   return savptr;
{

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


#30742

FromMalcolm McLean <malcolm.mclean5@btinternet.com>
Date2013-01-29 09:57 -0800
Message-ID<5a40af1f-3db0-4c6f-89e7-8609a7cad443@googlegroups.com>
In reply to#30737
On Tuesday, January 29, 2013 4:17:22 PM UTC, ssm...@gmail.com wrote:
> On Tuesday, January 22, 2013 1:14:18 PM UTC-5, Malcolm McLean wrote:
> 
> My own version is simply called strip(), but for a library you would probably want to rename it:
>
It's got the str prefix which indicates a standard library string function.
 

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


#30760

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2013-01-30 03:46 +0000
Message-ID<0.aeccae69fec7a325139c.20130130034630GMT.87d2wn2uzt.fsf@bsb.me.uk>
In reply to#30737
ssmitch@gmail.com writes:
<snip>
> Besides the obvious candidates, I've also found useful on a number of
> occasions a function to strip unwanted characters (such as commas or
> dollar signs in numeric values) from a string before further
> processing.  My own version is simply called strip(), but for a
> library you would probably want to rename it:
>
> /*
> *  remove unwanted characters from string
> *
> *  call as strip(char *str, *unwanted)
> *
> *  where "str" is the string to process and "unwanted" is a null-
> *  terminated string containing the characters to be stripped.
> *
> *  returns pointer to modified string
> */
>
> char *strip(char *str, char *unwanted) {
>    char *cp, *savptr;
>    savptr = str;
>    cp = str - 1;

That's, technically, problematic.  If str points to that start of an
array, the standard does not permit you to form the pointer str - 1,
even if you do nothing with it!

>    while (*++cp = *str++)
> 	   if (strchr(unwanted, *cp) != NULL)
> 		 --cp;

I think the fix is simpler than the original:

     cp = str;
     while (*cp = *str++)
	   if (strchr(unwanted, *cp) == NULL)
		 cp++;

I such cases I tend to write:

  while (*cp = *str++)
      cp += strchr(unwanted, *cp) == NULL;

but similar things have caused me to accused of all sorts of barbarism,
so I won't suggest you do likewise!

>    return savptr;
> {

} I think.


-- 
Ben.

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


#30810

FromTim Rentsch <txr@alumni.caltech.edu>
Date2013-01-31 14:50 -0800
Message-ID<kfna9rpdl1a.fsf@x-alumni2.alumni.caltech.edu>
In reply to#30760
Ben Bacarisse <ben.usenet@bsb.me.uk> writes:

> ssmitch@gmail.com writes:
> <snip>
>> Besides the obvious candidates, I've also found useful on a number of
>> occasions a function to strip unwanted characters (such as commas or
>> dollar signs in numeric values) from a string before further
>> processing.  My own version is simply called strip(), but for a
>> library you would probably want to rename it:
>>
>> /*
>> *  remove unwanted characters from string
>> *
>> *  call as strip(char *str, *unwanted)
>> *
>> *  where "str" is the string to process and "unwanted" is a null-
>> *  terminated string containing the characters to be stripped.
>> *
>> *  returns pointer to modified string
>> */
>>
>> char *strip(char *str, char *unwanted) {
>>    char *cp, *savptr;
>>    savptr = str;
>>    cp = str - 1;
>
> That's, technically, problematic.  If str points to that start of
> an array, the standard does not permit you to form the pointer
> str - 1, even if you do nothing with it!
>
>>    while (*++cp = *str++)
>> 	   if (strchr(unwanted, *cp) != NULL)
>> 		 --cp;
>
> I think the fix is simpler than the original:
>
>      cp = str;
>      while (*cp = *str++)
> 	   if (strchr(unwanted, *cp) == NULL)
> 		 cp++;
>
> I such cases I tend to write:
>
>   while (*cp = *str++)
>       cp += strchr(unwanted, *cp) == NULL;
>
> but similar things have caused me to accused of all sorts of
> barbarism, so I won't suggest you do likewise!

I was inspired by your examples to look for a short and simple
implementation.  I came up with this:

    char *
    eliminate( char *to_shrink, const char *unwanted ){
        char  *p = to_shrink,  *q = p;
        do  q += strspn( q, unwanted );  while(  *p++ = *q++  );
        return  to_shrink;
    }

I think it's easy to see that all 'unwanted' bytes are skipped
and only values not in 'unwanted' are copied.

And now let the barbarism accusers say what they will!

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


#30868

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2013-02-02 02:45 +0000
Message-ID<0.1d9ad443741c5d720c3b.20130202024542GMT.87fw1f77s9.fsf@bsb.me.uk>
In reply to#30810
Tim Rentsch <txr@alumni.caltech.edu> writes:

> Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
>
>> ssmitch@gmail.com writes:
>> <snip>
>>> Besides the obvious candidates, I've also found useful on a number of
>>> occasions a function to strip unwanted characters (such as commas or
>>> dollar signs in numeric values) from a string before further
>>> processing.  My own version is simply called strip(), but for a
>>> library you would probably want to rename it:
>>>
>>> /*
>>> *  remove unwanted characters from string
>>> *
>>> *  call as strip(char *str, *unwanted)
>>> *
>>> *  where "str" is the string to process and "unwanted" is a null-
>>> *  terminated string containing the characters to be stripped.
>>> *
>>> *  returns pointer to modified string
>>> */
>>>
>>> char *strip(char *str, char *unwanted) {
>>>    char *cp, *savptr;
>>>    savptr = str;
>>>    cp = str - 1;
>>
>> That's, technically, problematic.  If str points to that start of
>> an array, the standard does not permit you to form the pointer
>> str - 1, even if you do nothing with it!
>>
>>>    while (*++cp = *str++)
>>> 	   if (strchr(unwanted, *cp) != NULL)
>>> 		 --cp;
>>
>> I think the fix is simpler than the original:
>>
>>      cp = str;
>>      while (*cp = *str++)
>> 	   if (strchr(unwanted, *cp) == NULL)
>> 		 cp++;
>>
>> I such cases I tend to write:
>>
>>   while (*cp = *str++)
>>       cp += strchr(unwanted, *cp) == NULL;
>>
>> but similar things have caused me to accused of all sorts of
>> barbarism, so I won't suggest you do likewise!
>
> I was inspired by your examples to look for a short and simple
> implementation.  I came up with this:

Well, I was suggesting a simple fix rather than a simple alternative.

>     char *
>     eliminate( char *to_shrink, const char *unwanted ){
>         char  *p = to_shrink,  *q = p;
>         do  q += strspn( q, unwanted );  while(  *p++ = *q++  );
>         return  to_shrink;
>     }
>
> I think it's easy to see that all 'unwanted' bytes are skipped
> and only values not in 'unwanted' are copied.
>
> And now let the barbarism accusers say what they will!

That's nice (expect for the layout!) and I don't think there is any
barbarism involved (where could it be?).

-- 
Ben.

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


Page 1 of 2  [1] 2  Next page →

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


csiph-web