📄 strio.c
字号:
/************************************************************************* * * $Id: strio.c,v 1.1 2001/06/07 08:23:02 fjfranklin Exp $ * * Copyright (C) 1998 Bjorn Reese and Daniel Stenberg. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. * ************************************************************************//* * TODO * - StrToLongDouble */ static const char rcsid[] = "@(#)$Id: strio.c,v 1.1 2001/06/07 08:23:02 fjfranklin Exp $";#if defined(unix) || defined(__xlC__)# define PLATFORM_UNIX#elif defined(WIN32) || defined(_WIN32)# define PLATFORM_WIN32#elif defined(AMIGA) && defined(__GNUC__)# define PLATFORM_UNIX#endif#if defined(__STDC__) && (__STDC_VERSION__ >= 199901L)# define TRIO_C99#endif#include "strio.h"#include <string.h>#include <ctype.h>#include <stdarg.h>#include <time.h>#include <math.h>#ifndef DEBUG# define NDEBUG#endif#include <assert.h>#ifndef NULL# define NULL 0#endif#define NIL ((char)0)#ifndef FALSE# define FALSE (1 == 0)# define TRUE (! FALSE)#endif#define VALID(x) (NULL != (x))#define INVALID(x) (NULL == (x))#if defined(PLATFORM_UNIX)# define USE_STRCASECMP# define USE_STRNCASECMP# define USE_STRERROR#elif defined(PLATFORM_WIN32)# define USE_STRCMPI#endif/************************************************************************* * StrAppendMax */char *StrAppendMax(char *target, size_t max, const char *source){ assert(VALID(target)); assert(VALID(source)); assert(max > 0); max -= StrLength(target) + 1; return (max > 0) ? strncat(target, source, max) : target;}/************************************************************************* * StrCopyMax */char *StrCopyMax(char *target, size_t max, const char *source){ assert(VALID(target)); assert(VALID(source)); assert(max > 0); /* Includes != 0 */ target = strncpy(target, source, max - 1); target[max - 1] = (char)0; return target;}/************************************************************************* * StrDuplicate */char *StrDuplicate(const char *source){ char *target; assert(VALID(source)); target = (char *)malloc(StrLength(source) + 1); if (target) { StrCopy(target, source); } return target;}/************************************************************************* * StrDuplicateMax */char *StrDuplicateMax(const char *source, size_t max){ char *target; size_t len; assert(VALID(source)); assert(max > 0); /* Make room for string plus a terminating zero */ len = StrLength(source) + 1; if (len > max) { len = max; } target = (char *)malloc(len); if (target) { StrCopyMax(target, len, source); } return target;}/************************************************************************* * StrEqual */int StrEqual(const char *first, const char *second){ assert(VALID(first)); assert(VALID(second)); if (VALID(first) && VALID(second)) {#if defined(USE_STRCASECMP) return (0 == strcasecmp(first, second));#elif defined(USE_STRCMPI) return (0 == strcmpi(first, second));#else while ((*first != NIL) && (*second != NIL)) { if (toupper(*first) != toupper(*second)) { break; } first++; second++; } return ((*first == NIL) && (*second == NIL));#endif } return FALSE;}/************************************************************************* * StrEqualCase */int StrEqualCase(const char *first, const char *second){ assert(VALID(first)); assert(VALID(second)); if (VALID(first) && VALID(second)) { return (0 == strcmp(first, second)); } return FALSE;}/************************************************************************* * StrEqualCaseMax */int StrEqualCaseMax(const char *first, size_t max, const char *second){ assert(VALID(first)); assert(VALID(second)); if (VALID(first) && VALID(second)) { return (0 == strncmp(first, second, max)); } return FALSE;}/************************************************************************* * StrEqualMax */int StrEqualMax(const char *first, size_t max, const char *second){ assert(VALID(first)); assert(VALID(second)); if (VALID(first) && VALID(second)) {#if defined(USE_STRNCASECMP) return (0 == strncasecmp(first, second, max));#else /* Not adequately tested yet */ size_t cnt = 0; while ((*first != NIL) && (*second != NIL) && (cnt <= max)) { if (toupper(*first) != toupper(*second)) { break; } first++; second++; cnt++; } return ((cnt == max) || ((*first == NIL) && (*second == NIL)));#endif } return FALSE;}/************************************************************************* * StrError */const char *StrError(int errorNumber){#if defined(USE_STRERROR) return strerror(errorNumber);#else return "unknown";#endif}/************************************************************************* * StrFormatDate */size_t StrFormatDateMax(char *target, size_t max, const char *format, const struct tm *datetime){ assert(VALID(target)); assert(VALID(format)); assert(VALID(datetime)); assert(max > 0); return strftime(target, max, format, datetime);}/************************************************************************* * StrHash */unsigned long StrHash(const char *string, int type){ unsigned long value = 0L; char ch; assert(VALID(string)); switch (type) { case STRIO_HASH_PLAIN: while ( (ch = *string++) != NIL ) { value *= 31; value += (unsigned long)ch; } break; default: assert(FALSE); break; } return value;}/************************************************************************* * StrMatch */int StrMatch(char *string, char *pattern){ assert(VALID(string)); assert(VALID(pattern)); for (; ('*' != *pattern); ++pattern, ++string) { if (NIL == *string) { return (NIL == *pattern); } if ((toupper(*string) != toupper(*pattern)) && ('?' != *pattern)) { return FALSE; } } /* two-line patch to prevent *too* much recursiveness: */ while ('*' == pattern[1]) pattern++; do { if ( StrMatch(string, &pattern[1]) ) { return TRUE; } } while (*string++); return FALSE;}/************************************************************************* * StrMatchCase */int StrMatchCase(char *string, char *pattern){ assert(VALID(string)); assert(VALID(pattern)); for (; ('*' != *pattern); ++pattern, ++string) { if (NIL == *string) { return (NIL == *pattern); } if ((*string != *pattern) && ('?' != *pattern)) { return FALSE; } } /* two-line patch to prevent *too* much recursiveness: */ while ('*' == pattern[1]) pattern++; do { if ( StrMatchCase(string, &pattern[1]) ) { return TRUE; } } while (*string++); return FALSE;}/************************************************************************* * StrSpanFunction * * Untested */size_t StrSpanFunction(char *source, int (*Function)(int)){ size_t count = 0; assert(VALID(source)); assert(VALID(Function)); while (*source != NIL) { if (Function(*source)) break; /* while */ source++; count++; } return count;}/************************************************************************* * StrSubstringMax */char *StrSubstringMax(const char *string, size_t max, const char *find){ size_t count; size_t size; char *result = NULL; assert(VALID(string)); assert(VALID(find)); size = StrLength(find); if (size <= max) { for (count = 0; count <= max - size; count++) { if (StrEqualMax(find, size, &string[count])) { result = (char *)&string[count]; break; } } } return result;}/************************************************************************* * StrToDouble * * double ::= [ <sign> ] * ( <number> | * <number> <decimal_point> <number> | * <decimal_point> <number> ) * [ <exponential> [ <sign> ] <number> ] * number ::= 1*( <digit> ) * digit ::= ( '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' ) * exponential ::= ( 'e' | 'E' ) * sign ::= ( '-' | '+' ) * decimal_point ::= '.' */double StrToDouble(const char *source, const char **endp){#if defined(TRIO_C99) return strtod(source, endp);#else /* Preliminary code */ int isNegative = FALSE; int isExponentNegative = FALSE; unsigned long integer = 0; unsigned long fraction = 0; unsigned long fracdiv = 1; unsigned long exponent = 0; double value = 0.0; /* First try hex-floats */ if ((source[0] == '0') && ((source[1] == 'x') || (source[1] == 'X'))) { source += 2; while (isxdigit((int)*source)) { integer *= 16; integer += (isdigit((int)*source) ? (*source - '0') : (isupper((int)*source) ? (*source - 'A') : (*source - 'a'))); source++; } if (*source == '.') { source++; while (isxdigit((int)*source)) { fraction *= 16; fraction += (isdigit((int)*source) ? (*source - '0') : (isupper((int)*source) ? (*source - 'A') : (*source - 'a'))); fracdiv *= 16; source++; } if ((*source == 'p') || (*source == 'P')) { source++; if ((*source == '+') || (*source == '-')) { isExponentNegative = (*source == '-'); source++; } while (isdigit((int)*source)) { exponent *= 10; exponent += (*source - '0'); source++; } } } } else /* Then try normal decimal floats */ { isNegative = (*source == '-'); /* Skip sign */ if ((*source == '+') || (*source == '-')) source++; /* Integer part */ while (isdigit((int)*source)) { integer *= 10; integer += (*source - '0'); source++; } if (*source == '.') { source++; /* skip decimal point */ while (isdigit((int)*source)) { fraction *= 10; fraction += (*source - '0'); fracdiv *= 10; source++; } } if ((*source == 'e') || (*source == 'E')) { source++; /* Skip exponential indicator */ isExponentNegative = (*source == '-'); if ((*source == '+') || (*source == '-')) source++; while (isdigit((int)*source)) { exponent *= 10; exponent += (*source - '0'); source++; } } } value = (double)integer; if (fraction != 0) { value += (double)fraction / (double)fracdiv; } if (exponent != 0) { if (isExponentNegative) value /= pow((double)10, (double)exponent); else value *= pow((double)10, (double)exponent); } if (isNegative) value = -value; if (endp) *endp = source; return value;#endif}/************************************************************************* * StrToFloat */float StrToFloat(const char *source, const char **endp){#if defined(TRIO_C99) return strtof(source, endp);#else return (float)StrToDouble(source, endp);#endif}/************************************************************************* * StrToUpper */int StrToUpper(char *target){ int i = 0; assert(VALID(target)); while (NIL != *target) { *target = toupper(*target); target++; i++; } return i;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -