Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #30512 > unrolled thread
| Started by | Malcolm McLean <malcolm.mclean5@btinternet.com> |
|---|---|
| First post | 2013-01-22 10:14 -0800 |
| Last post | 2013-02-03 14:33 -0800 |
| Articles | 20 on this page of 21 — 14 participants |
Back to article view | Back to comp.lang.c
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 →
| From | Malcolm McLean <malcolm.mclean5@btinternet.com> |
|---|---|
| Date | 2013-01-22 10:14 -0800 |
| Subject | strsup - 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]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2013-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]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2013-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]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2013-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]
| From | Johann Klammer <klammerj@NOSPAM.a1.net> |
|---|---|
| Date | 2013-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]
| From | Jorgen Grahn <grahn+nntp@snipabacken.se> |
|---|---|
| Date | 2013-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]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2013-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]
| From | Bjorn Augestad <bjorn.augestad@gmail.com> |
|---|---|
| Date | 2013-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]
| From | Dr Nick <nospam-4@temporary-address.org.uk> |
|---|---|
| Date | 2013-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]
| From | Malcolm McLean <malcolm.mclean5@btinternet.com> |
|---|---|
| Date | 2013-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]
| From | "BartC" <bc@freeuk.com> |
|---|---|
| Date | 2013-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]
| From | Malcolm McLean <malcolm.mclean5@btinternet.com> |
|---|---|
| Date | 2013-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]
| From | John McCue <jmccue@jmcbsd0.hsd1.ma.comcast.net> |
|---|---|
| Date | 2013-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]
| From | JohnF <john@please.see.sig.for.email.com> |
|---|---|
| Date | 2013-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]
| From | 88888 Dihedral <dihedral88888@googlemail.com> |
|---|---|
| Date | 2013-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]
| From | ssmitch@gmail.com |
|---|---|
| Date | 2013-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]
| From | Malcolm McLean <malcolm.mclean5@btinternet.com> |
|---|---|
| Date | 2013-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]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2013-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]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2013-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]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2013-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