鼠标一般多少钱:ANSI C 字符串库函数的实现
来源:百度文库 编辑:九乡新闻网 时间:2024/07/14 00:50:51
Note: part of this article is referenced from Microsoft CRT Source Code in Visual Studio 6.0.
If you wanna become an Embedded Software Enginner or Staff C Programmer, you must have some fundamental ideas on how the ANSI C string library functions were implemented. Furthermore, these functions are very common in an C/C++ programmer interview, esp., strrev() (note: strrev() is not ANSI C standard) and strtok(). I'm now trying to implment all of these string functions for your reference. Please debug them for me if possible.
strrev()/* Referenced from Microsoft CRT source code, efficient and easy to understand */char* strrev(char* s){ char* left = s; char* right = s, c; while(*right++); right -= 2; while(left < right) c = *left, *left++ = *right, *right-- = c; return s;}strtok()
/* Efficient(?) and easy to understand. It may be more efficient in Microsoft CRT source code, but it's very hard to understand */char* strtok(char* s, const char* ct){ static char* ntok; /* Next token */ char* cp; /* For moving s */ char* cq; /* For moving ct */ if ( !s ) s = ntok; /* Not first call */ /* Skip the non-token characters, i.e., ones in ct */ cp = s; while ( *cp ) { cq = (char*)ct; while ( *cq && *cp-*cq ) ++cq; if ( !*cq ) /* Found the token beginning */ { s = cp; /* For returning */ break; } ++cp; } if ( !*cp ) /* No more token can be found. */ return NULL; /* else: found a new word */ cp = s; while ( *cp ) { cq = (char*)ct; while ( *cq && *cp-*cq ) ++cq; if ( *cq ) /* Found a new word ending */ { *cp = 0; /* Set to '\0' as definition says */ ntok = cp + 1; /* Move ntok to next search beginning */ return s; } ++cp; } ntok = cp; /* Not: ntok = cp + 1 */ return s; /* For the last token */}strstr()
/* Referenced from Microsoft CRT source code, efficient and easy to understand */char* strstr(const char* cs, const char* ct){ char* cp = (char*)cs; char* s1, * s2; if ( !*ct ) return (char*)cs; while ( *cp ) { s1 = cp; s2 = (char*)ct; while ( *s1 && *s2 && !(*s1-*s2) ) ++s1, ++s2; if ( !*s2 ) return cp; ++cp; } return NULL;}strlen()
/* Referenced from Microsoft CRT source code, efficient and easy to understand */int strlen(const char* cs){ const char* e = cs; while ( *e++ ); return (int)(e - cs - 1);}strcpy()
/* Efficient and easy to understand */char* strcpy(char* s, const char* ct){ char* start = s; while ( *s++ = *ct++ ); return start;}strcat()
/* Referenced from Microsoft CRT source code, efficient and easy to understand */char* strcat(char* s, const char* ct){ char* start = s; while ( *s ) ++s; while ( *s++ = *ct++ ); return start;}strcmp()
/* Referenced from Microsoft CRT source code, efficient and easy to understand */int strcmp(const char* cs, const char* ct){ int ret; while ( !(ret = *(unsigned char*)cs-*(unsigned char*)ct) && *ct ) ++cs, ++ct; return ret;}strchr()
/* Referenced from Microsoft CRT source code, efficient and easy to understand */char* strchr(const char* cs, int c){ while ( *cs && *cs!=(char)c ) ++cs; return *cs == (char)c ? (char*)cs : NULL; /* Cannot handle c == NULL : return *cs ? (char*)cs : NULL; */}strspn()
/* Efficient(?) and easy to understand. It may be more efficient in Microsoft CRT source code, but it's very hard to understand */int strspn(const char* cs, const char* ct){ char* cp = (char*)cs; char* cq; while ( *cp ) { cq = (char*)ct; while ( *cq && *cp-*cq ) ++cq; if ( !*cq ) return cp - cs; ++cp; } return cp - cs;}strcspn()
/* Efficient(?) and easy to understand. It may be more efficient in Microsoft CRT source code, but it's very hard to understand */int strcspn(const char* cs, const char* ct){ char* cp = (char*)cs; char* cq; while ( *cp ) { cq = (char*)ct; while ( *cq && *cp-*cq ) ++cq; if ( *cq ) return cp - cs; ++cp; } return cp - cs;}strpbrk()
/* Efficient(?) and easy to understand. It may be more efficient in Microsoft CRT source code, but it's very hard to understand */char* strpbrk(const char* cs, const char* ct){ char* cp = (char*)cs; char* cq; while ( *cp ) { cq = (char*)ct; while ( *cq && *cp-*cq ) ++cq; if ( *cq ) return (char*)cp; ++cp; } return NULL;}Microsoft CRT Source Code for strspn(), strcspn() and strpbrk()
The Microsoft CRT source code for strspn(), strcspn() and strpbrk() is very hard to understand. However, I will be dedicated to it in the near future :-). See the CRT code at your local disk VS6.0 was installed C:\Program Files\Microsoft Visual Studio\VC98\CRT\SRC\STRSPN.C or the code below I copied:
/****strspn.c - find length of initial substring of chars from a control string** Copyright (c) 1985-1997, Microsoft Corporation. All rights reserved.**Purpose:* defines strspn() - finds the length of the initial substring of* a string consisting entirely of characters from a control string.** defines strcspn()- finds the length of the initial substring of* a string consisting entirely of characters not in a control string.** defines strpbrk()- finds the index of the first character in a string* that is not in a control string********************************************************************************//* Determine which routine we're compiling for (default to STRSPN) */#define _STRSPN 1#define _STRCSPN 2#define _STRPBRK 3#if defined (SSTRCSPN)#define ROUTINE _STRCSPN#elif defined (SSTRPBRK)#define ROUTINE _STRPBRK#else /* defined (SSTRPBRK) */#define ROUTINE _STRSPN#endif /* defined (SSTRPBRK) */#include#include /****int strspn(string, control) - find init substring of control chars**Purpose:* Finds the index of the first character in string that does belong* to the set of characters specified by control. This is* equivalent to the length of the initial substring of string that* consists entirely of characters from control. The '\0' character* that terminates control is not considered in the matching process.**Entry:* char *string - string to search* char *control - string containing characters not to search for**Exit:* returns index of first char in string not in control**Exceptions:********************************************************************************//****int strcspn(string, control) - search for init substring w/o control chars**Purpose:* returns the index of the first character in string that belongs* to the set of characters specified by control. This is equivalent* to the length of the length of the initial substring of string* composed entirely of characters not in control. Null chars not* considered.**Entry:* char *string - string to search* char *control - set of characters not allowed in init substring**Exit:* returns the index of the first char in string* that is in the set of characters specified by control.**Exceptions:********************************************************************************//****char *strpbrk(string, control) - scans string for a character from control**Purpose:* Finds the first occurence in string of any character from* the control string.**Entry:* char *string - string to search in* char *control - string containing characters to search for**Exit:* returns a pointer to the first character from control found* in string.* returns NULL if string and control have no characters in common.**Exceptions:********************************************************************************//* Routine prototype */#if ROUTINE == _STRSPNsize_t __cdecl strspn (#elif ROUTINE == _STRCSPNsize_t __cdecl strcspn (#else /* ROUTINE == _STRCSPN */char * __cdecl strpbrk (#endif /* ROUTINE == _STRCSPN */ const char * string, const char * control ){ const unsigned char *str = string; const unsigned char *ctrl = control; unsigned char map[32]; int count; /* Clear out bit map */ for (count=0; count<32; count++) map[count] = 0; /* Set bits in control map */ while (*ctrl) { map[*ctrl >> 3] |= (1 << (*ctrl & 7)); ctrl++; }#if ROUTINE == _STRSPN /* 1st char NOT in control map stops search */ if (*str) { count=0; while (map[*str >> 3] & (1 << (*str & 7))) { count++; str++; } return(count); } return(0);#elif ROUTINE == _STRCSPN /* 1st char in control map stops search */ count=0; map[0] |= 1; /* null chars not considered */ while (!(map[*str >> 3] & (1 << (*str & 7)))) { count++; str++; } return(count);#else /* ROUTINE == _STRCSPN */ /* 1st char in control map stops search */ while (*str) { if (map[*str >> 3] & (1 << (*str & 7))) return((char *)str); str++; } return(NULL);#endif /* ROUTINE == _STRCSPN */}