📄 strtools.c
字号:
// ----------------------------------------------------------------------------// Copyright 2006-2007, Martin D. Flynn// All rights reserved// ----------------------------------------------------------------------------//// Licensed under the Apache License, Version 2.0 (the "License");// you may not use this file except in compliance with the License.// You may obtain a copy of the License at// // http://www.apache.org/licenses/LICENSE-2.0// // Unless required by applicable law or agreed to in writing, software// distributed under the License is distributed on an "AS IS" BASIS,// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.// See the License for the specific language governing permissions and// limitations under the License.//// ----------------------------------------------------------------------------// Description:// String tools// Various tools to providing string based parsing and encoding/decoding.// ---// Change History:// 2006/01/04 Martin D. Flynn// -Initial release// 2007/01/28 Martin D. Flynn// -WindowsCE port// -Added functions:// strTrimTrailing/strTrim/strCopy/strCopyID/strEndsWith// 2007/03/11 Martin D. Flynn// -Removed "on"/"yes" options in 'strParseBoolean'// -Added ability to parse "true"/"false" in 'strParseInt32'// ----------------------------------------------------------------------------#include "stdafx.h" // TARGET_WINCE#define SKIP_TRANSPORT_MEDIA_CHECK // only if TRANSPORT_MEDIA not used in this file #include "custom/defaults.h"#include <stdio.h>#include <stdlib.h>#include <string.h>#include <stdarg.h>#include <ctype.h>#if defined(TARGET_WINCE)#include <Windows.h>#endif#include "tools/strtools.h"// ----------------------------------------------------------------------------/* replacement for 'strnlen' (not all platforms support 'strnlen') */int strLength(const char *s, int maxLen){ if (maxLen >= 0) { // return strnlen(s, maxLen); int len = 0; for (len = 0; (len < maxLen) && s[len]; len++); return len; } else { return s? strlen(s) : 0; }}// ----------------------------------------------------------------------------/* trim trailing spaces from specified null-terminated string */char *strTrimTrailing(char *s){ if (s) { int len = strlen(s); if (len > 0) { // trim trailing spaces char *n = &s[len - 1]; for (; (n >= s) && isspace(*n); n--) { *n = 0; } } } return s;}/* return string starting at first non-space, and clobber all trailing spaces, in-place */char *strTrim(char *s){ if (s) { // trim trailing space strTrimTrailing(s); // advance start of string to first non-space while (*s && isspace(*s)) { s++; } } return s;}// ----------------------------------------------------------------------------/* copy 'maxLen' characters from 's' to 'd', and make sure 'd' is terminated */// (similar to 'strncpy', but does best attempt to terminate 'd')char *strCopy(char *d, int dlen, const char *s, int maxLen){ /* validate arguments */ if (!d || (dlen <= 0)) { // no destination return d; } else if (!s || (maxLen == 0) || !*s) { // no source d[0] = 0; return d; } /* default length */ if (maxLen < 0) { maxLen = strlen(s) + 1; // include null terminator } /* copy */ int sndx = 0, dndx = 0; for (; (sndx < maxLen) && (dndx < dlen) && s[sndx]; sndx++) { d[dndx++] = s[sndx]; } /* terminate destination */ if (dndx < dlen) { d[dndx] = 0; } /* return destination buffer */ return d;}/* filter copy 'maxLen' characters from 's' to 'd', and make sure 'd' is terminated */// (similar to 'strCopy', but filters out invalid ID characters)// Filter: destination may contain only 'A'..'Z', 'a'..'z, '0'..'9', '-', '.'char *strCopyID(char *d, int dlen, const char *s, int maxLen){ /* validate arguments */ if (!d || (dlen <= 0)) { // no destination return d; } else if (!s || (maxLen == 0) || !*s) { // no source d[0] = 0; return d; } /* default length */ if (maxLen < 0) { maxLen = strlen(s) + 1; // include null terminator } /* copy (with filter) */ int sndx = 0, dndx = 0; for (;(sndx < maxLen) && (dndx < dlen) && s[sndx]; sndx++) { if (isalnum(s[sndx]) || (s[sndx] == '.') || (s[sndx] == '-')) { d[dndx++] = islower(s[sndx])? toupper(s[sndx]) : s[sndx]; } } /* terminate destination */ if (dndx < dlen) { d[dndx] = 0; } /* return destination buffer */ return d;}#if defined(TARGET_WINCE)/* copy 'maxLen' characters from 's' to wide char array 'd', and make sure 'd' is terminated */TCHAR *strWideCopy(TCHAR *d, int dlen, const char *s, int maxLen){ /* validate arguments */ if (!d || (dlen <= 0)) { // no destination return d; } else if (!s || (maxLen == 0) || !*s) { // no source d[0] = 0; return d; } /* default length */ if (maxLen < 0) { maxLen = strlen(s) + 1; // include null terminator } /* reset maxLen if necessary */ // 'maxLen' cannot be larger than 'dlen' if (dlen < maxLen) { maxLen = dlen; } /* multibyte copy */ int n = MultiByteToWideChar(CP_UTF8, 0, s, maxLen, d, dlen); /* terminate destination */ if (n < dlen) { d[n] = 0; } /* return destination buffer */ return d; }#endif// ----------------------------------------------------------------------------/* return true is strings are equal */utBool strEquals(const char *s, const char *v){ return (s && v && (strcmp(s,v) == 0))? utTrue : utFalse;}/* return true is strings are equal, without regard to case */utBool strEqualsIgnoreCase(const char *s, const char *v){ // (not all platforms support 'strcasecmp') //return (s && v && (strcasecmp(s,v) == 0))? utTrue : utFalse; if (s && v) { while (*s && *v) { char _s = *s, sc = isupper(_s)? tolower(_s) : _s; char _v = *v, vc = isupper(_v)? tolower(_v) : _v; if (vc != sc) { return utFalse; } s++; v++; } return (!*s && !*v)? utTrue : utFalse; // true if at end-of-string for both strings } else { return utFalse; }}// ----------------------------------------------------------------------------/* return true if the target string starts with the value string */utBool strStartsWith(const char *s, const char *v){ return (s && v && (strncmp(s,v,strlen(v)) == 0))? utTrue : utFalse;}/* return true if the target string starts with the value string, without regard to case */utBool strStartsWithIgnoreCase(const char *s, const char *v){ // (not all platforms support 'strcasecmp') //return (s && v && (strncasecmp(s,v,strlen(v)) == 0))? utTrue : utFalse; if (s && v) { while (*s && *v) { char _s = *s, sc = isupper(_s)? tolower(_s) : _s; char _v = *v, vc = isupper(_v)? tolower(_v) : _v; if (vc != sc) { return utFalse; } s++; v++; } return (!*v)? utTrue : utFalse; // true if 'v' at end-of-string } else { return utFalse; }}// ----------------------------------------------------------------------------/* return true if the target string ends with the value string */utBool strEndsWith(const char *s, const char *v){ if (!s || !v) { return utFalse; } else { Int32 sLen = strlen(s); Int32 vLen = strlen(v); if (vLen > sLen) { return utFalse; } else { s += (sLen - vLen); return strEquals(s,v); } }}/* return true if the target string ends with the value string */utBool strEndsWithIgnoreCase(const char *s, const char *v){ if (!s || !v) { return utFalse; } else { Int32 sLen = strlen(s); Int32 vLen = strlen(v); if (vLen > sLen) { return utFalse; } else { s += (sLen - vLen); return strEqualsIgnoreCase(s,v); } }}// ----------------------------------------------------------------------------// See also "Boyer and Moore searching algorithm": // http://www.csr.uvic.ca/~nigelh/Publications/stringsearch.pdf// "Simplified" BM algorithm:// const char *strIndexOf(const char *s, const char *p) // {// // 'sLen' must be >= 'pLen', and 'pLen' must be <= 256// Int32 sLen = strlen(s);// Int32 pLen = strlen(p);// if (sLen >= pLen) {// // initialize for search// UInt8 delta[256];// memset(delta12, pLen, 256);// for (Int32 j = 0; j < pLen - 1; j++) { delta12[(UInt8)p[j]] = pLen - j - 1; }// UInt8 lastch = (UInt8)p[patlen - 1];// // search// for (Int32 i = patlen - 1; i < sLen;) {// UInt8 ch = (UInt8)s[i];// if (ch == lastch) {// Int32 ndx = i - pLen + 1;// if (!strcmp(s + ndx, p, pLen)) {// return s + ndx;// }// }// i += delta12[ch]; // <-- may advance beyond sLen// // for (Int32 j = i + delta12[ch]; i <= j; i++) { // // if (!*(s+i)) { return (char*)0; }// // }// }// }// return (char*)0;// }/* return index of value string in target string */const char *strIndexOf(const char *s, const char *p){ if (!s || !p) { // null string specified return (char*)0; } else { Int32 pLen = strlen(p); for (;*s; s++) { if ((*s == *p) && (strncmp(s,p,pLen) == 0)) { return s; } } return (char*)0; }}// ----------------------------------------------------------------------------/* return last index of value char in target string */// note: not all platforms support 'rindex'const char *strLastIndexOfChar(const char *s, char v){ if (!s) { // null string specified return (char*)0; } else { Int32 sLen = (Int32)strlen(s); // must be signed if (!v) { return &s[sLen]; // point to terminator } else { for (; sLen >= 0; sLen--) { if (s[sLen] == v) { return &s[sLen]; } } return (char*)0; } }}// ----------------------------------------------------------------------------/* upshift in-place */char *strToUpperCase(char *s){ if (s) { char *d = s; for (; *d; d++) { if (islower(*d)) { *d = toupper(*d); } } } return s;}/* downshift in-place */char *strToLowerCase(char *s){ if (s) { char *d = s; for (; *d; d++) { if (isupper(*d)) { *d = tolower(*d);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -