Malcolm McLean said:
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)))