📄 strsplit.c
字号:
/* String splitter functions Copyright (C) 1999, Joe Orton <joe@orton.demon.co.uk> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: strsplit.c,v 1.11.2.1 1999/07/20 12:53:58 joe Exp $*/#ifdef HAVE_CONFIG_H#include <config.h>#endif#ifdef HAVE_STDLIB_H#include <stdlib.h>#endif#ifdef HAVE_STRING_H#include <string.h>#endif#ifdef HAVE_UNISTD_H#include <unistd.h>#endif/* glibc2.1 has strdup as a macro */#ifndef strdupchar *strdup (const char *);#endif#include "strsplit.h"char **strsplit( const char *str, const char separator, const char *quotes, const char *whitespace ) { char **comps; const char *pnt, *quot = NULL, *start, *end; /* The start of the current component */ int count, /* The number of components */ iswhite, /* is it whitespace */ issep, /* is it the separator */ curr, /* current component index */ length, /* length of component */ leading_wspace; /* in leading whitespace still? */ /* Inefficient, but easier - first off, count the number of * components we have. */ count = 1; for( pnt = str; *pnt!='\0'; pnt++ ) { if( quotes != NULL ) { quot = strchr( quotes, *pnt ); } if( quot != NULL ) { /* We found a quote, so skip till the next quote */ for( pnt++; (*pnt!=*quot) && (*pnt!='\0'); pnt++ ) /* nullop */; } else if( *pnt == separator ) { count++; } } /* Now, have got the number of components. * Allocate the comps array. +1 for the NULL */ comps = malloc( sizeof(char *) * (count + 1) ); comps[count] = NULL; quot = end = start = NULL; curr = 0; leading_wspace = 1; /* Now fill in the array */ for( pnt = str; *pnt != '\0'; pnt++ ) { /* What is the current character - quote, whitespace, separator? */ if( quotes != NULL ) { quot = strchr( quotes, *pnt ); } iswhite = (whitespace!=NULL) && (strchr( whitespace, *pnt ) != NULL ); issep = (*pnt == separator); /* What to do? */ if( leading_wspace ) { if( quot!=NULL ) { /* Quoted bit */ start = pnt; length = 1; leading_wspace = 0; } else if( issep ) { /* Zero-length component */ comps[curr++] = strdup(""); } else if( !iswhite ) { start = end = pnt; length = 1; leading_wspace = 0; } } else { if( quot!=NULL ) { /* Quoted bit */ length++; } else if( issep ) { /* End of component - enter it into the array */ length = (end - start) + 1; comps[curr] = malloc( length+1 ); memcpy( comps[curr], start, length ); comps[curr][length] = '\0'; curr++; leading_wspace = 1; } else if( !iswhite ) { /* Not whitespace - update end marker */ end = pnt; } } if( quot != NULL ) { /* Skip to closing quote */ for( pnt++; *pnt!=*quot && *pnt != '\0'; ++pnt ) /* nullop */; /* Last non-wspace char is closing quote */ end = pnt; } } /* Handle final component */ if( leading_wspace ) { comps[curr] = strdup( "" ); } else { /* End of component - enter it into the array */ length = (end - start) + 1; comps[curr] = malloc( length+1 ); memcpy( comps[curr], start, length ); comps[curr][length] = '\0'; } return comps;}char **strpairs( const char *str, const char compsep, const char kvsep, const char *quotes, const char *whitespace ) { char **comps, **curr, **pairs, *split; int count = 0, n, length; comps = strsplit( str, compsep, quotes, whitespace ); for( curr = comps; *curr!=NULL; curr++ ) { count++; } /* Allocate space for 2* as many components as strsplit returned, * +2 for the NULLS. */ pairs = malloc( (2*count+2) * sizeof(char *) ); for( n = 0; n < count; n++ ) { /* Find the split */ split = strchr( comps[n], kvsep ); if( split == NULL ) { /* No seperator found */ length = strlen(comps[n]); } else { length = split-comps[n]; } /* Enter the key into the array */ pairs[2*n] = malloc( length+1 ); memcpy( pairs[2*n], comps[n], length ); pairs[2*n][length] = '\0'; /* Now the value. */ if( split == NULL ) { pairs[2*n+1] = NULL; } else { /* Length is -1 to skip the separator. */ length = strlen( comps[n] ) - (length+1); pairs[2*n+1] = malloc( length+1 ); memcpy( pairs[2*n+1], split+1, length ); pairs[2*n+1][length] = '\0'; } } pairs[2*count] = pairs[2*count+1] = NULL; return pairs;}void strsplit_free( char **components ) { char **pnt = components; while( *pnt != NULL ) { free( *pnt ); pnt++; }}void strpairs_free( char **pairs ) { int n; for( n = 0; pairs[n] != NULL; n+=2 ) { free( pairs[n] ); if( pairs[n+1] != NULL ) free( pairs[n+1] ); }}char *strstrip( const char *str, const char ch ) { size_t len = strlen( str ); char *ret; if( str[len-1] == ch ) { len--; } if( str[0] == ch ) { len--; str++; } ret = malloc( len + 1 ); memcpy( ret, str, len ); ret[len] = '\0'; return ret;}#ifdef STRSPLIT_TEST#include <stdio.h>int main( int argc, char *argv[] ) { char *str, sep, **comps, *wspace, *quotes; int count; if( argc < 3 ) { printf( "Usage: strsplit <sep> <string> [whitespace] [quotes]\n" ); return -1; } sep = *argv[1]; str = argv[2]; if( argc > 3 ) { wspace = argv[3]; } else { wspace = " "; } if( argc > 4 ) { quotes = argv[4]; } else { quotes = "\""; } printf( "String: [%s] Separator: `%c' Whitespace: [%s] Quotes: [%s]\n", str, sep, wspace, quotes ); comps = strsplit( str, sep, quotes, wspace ); count = 0; do { printf( "Component #%d: [%s]\n", count, comps[count] ); } while( comps[++count] != NULL ); return 0;}#endif#ifdef STRPAIRS_TEST#include <stdio.h>int main( int argc, char *argv[] ) { char *str, compsep, kvsep, **comps, *wspace, *quotes; int count; if( argc < 4 ) { printf( "Usage: strpairs <compsep> <kvsep> <string> [whitespace] [quotes]\n" ); return -1; } compsep = *argv[1]; kvsep = *argv[2]; str = argv[3]; if( argc > 4 ) { wspace = argv[4]; } else { wspace = " "; } if( argc > 5 ) { quotes = argv[5]; } else { quotes = "\""; } printf( "String: [%s] CompSep: `%c' K/VSep: `%c'\nWhitespace: [%s] Quotes: [%s]\n", str, compsep, kvsep, wspace, quotes ); comps = strpairs( str, compsep, kvsep, quotes, wspace ); count = 0; do { printf( "Component #%d: Key [%s] Value [%s]\n", count, comps[count], comps[count+1] ); } while( comps[(count+=2)] != NULL ); return 0;}#endif/* variables: * * Local variables: * compile-command: "gcc -g -O2 -Wall -I.. -ansi -DHAVE_CONFIG_H -DSTRSPLIT_TEST -o strsplit strsplit.c" * End: */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -