Title: Implementing string manipulation functions commonly used in Linux C
Topic Analysis:
First, the interview may often encounter such problems: such as strcpy, memcpy, strstr
Second, the reference to the Linux kernel code, to the Linux great God thank you, the code is quite exquisite, here to share with you
Algorithm implementation:
/* * LINUX/LIB/STRING.C * * Copyright (c) 1991, 1992 Linus Torvalds *//* * Stupid library routines. The optimized versions should generally be found * as inline code in <asm-xx/string.h> * * These is buggy as well. * * * * Fri June 1999, Ingo oeser <[email protected]> *-Added STRSEP () which would replace Strtok () soon (be Cause strsep () is * reentrant and should be faster). Use only Strsep () on new code, please. * * * Sat 2002, Jason Thomas <[email protected]>, * Matthew Hawkins <[email p rotected]> *-Kissed Strtok () Goodbye */#include "string_fun.h"/** * strnicmp-case insensitive, length-limited stri ng comparison * @s1: one string * @s2: The other String * @len: The maximum number of characters to compare */int strnicmp (const char *S1, const char *S2, unsigned int len) {/* Yes, Virginia, it had better be unsigned */unsigned char C1, c2;if (!len) return 0;do {c1 = *S1++;C2 = *s2++;if (!c1 | | !C2) break;if (c1 == C2) Continue;c1 = ToLower (c1); c2 = ToLower (C2); if (c1! = C2) break;} while (--len), return (int) c1-(int) C2;} int strcasecmp (const char *S1, const char *s2) {int C1, C2;do {c1 = ToLower (*s1++); c2 = ToLower (*s2++);} while (C1 = C2 &A mp;& C1! = 0); return c1-c2;} int strncasecmp (const char *S1, const char *S2, unsigned int n) {int C1, C2;do {c1 = ToLower (*s1++); c2 = ToLower (*s2++);} W Hile ((--n > 0) && c1 = = C2 && C1! = 0); return c1-c2;} /** * Strcpy-copy a%nul terminated string * @dest: Where to copy the string to * @src: Where to copy the string from */ Char *strcpy (char *dest, const char *src) {char *tmp = dest;while ((*dest++ = *src++)! = ' + ') */Nothing */;return tmp;} /** * Strncpy-copy a length-limited,%nul-terminated string * @dest: Where to copy the string to * @src: Where to copy t He string from * @count: The maximum number of bytes to copy * *, the result is not%nul-terminated if the source exceeds * @count bytes. * * In the case where the length of @sRC is less than that of * count, the remainder of @dest would be padded with%nul. * */char *strncpy (char *dest, const char *SRC, unsigned int count) {char *tmp = dest;while (count) {if (*tmp = *SRC)! = 0) src++;tmp++;count--;} return dest;} /** * Strcat-append One%nul-terminated string to another * @dest: the string to being appended to * @src: the string to AP Pend to it */char *strcat (char *dest, const char *src) {char *tmp = dest;while (*dest) dest++;while ((*dest++ = *src++)! = ' "); return tmp;} /** * Strncat-append a length-limited,%nul-terminated string to another * @dest: the string to being appended to * @src: T He string to append to it * @count: The maximum numbers of bytes to copy * * Note this in contrast to strncpy (), Strncat () Ensures the result is * terminated. */char *strncat (char *dest, const char *SRC, unsigned int count) {char *tmp = dest;if (count) {while (*dest) dest++;while ((*dest++ = *src++)! = 0) {if (--count = = 0) {*dest = ' + '; break;}}} RetuRN tmp;} /** * Strcmp-compare Strings * @cs: one string * @ct: Another string */int strcmp (const char *CS, const char *ct) {UN Signed Char C1, C2;while (1) {c1 = *CS++;C2 = *ct++;if (c1! = C2) return C1 < C2? -1:1;if (!C1) break;} return 0;} /** * Strncmp-compare-length-limited strings * @cs: one string * @ct: Another string * @count: The maximum number of Bytes to compare */int strncmp (const char *CS, const char *CT, unsigned int count) {unsigned char C1, C2;while (count) {C1 = *CS++;C2 = *ct++;if (c1! = C2) return C1 < C2? -1:1;if (!C1) break;count--;} return 0;} /** * Strchr-find The first occurrence of a character in a string * @s:the string to being searched * @c:the character to Search for */char *strchr (const char *s, int. c) {for (; *s! = (char) c; ++s) if (*s = = ' + ') return Null;return (char *) s;} /** * Strrchr-find The last occurrence of a character in a string * @s:the string to being searched * @c:the character to Search for */char *strrchr (const char *s, INT c) {const char *p = s + strlen (s); do {if (*p = = (char) c) return (char *) p; } while (--p >= s); return NULL;} /** * Strnchr-find A character in a length limited string * @s:the string to be searched * @count: the number of Charac ters to being searched * @c:the character to search for */char *strnchr (const char *s, unsigned int count, int. c) {for (; cou nt--&& *s! = ' + '; ++s) if (*s = = (char) c) return (char *) S;return NULL;} /** * skip_spaces-removes leading whitespace from @str. * @str: The string to is stripped. * * Returns A pointer to the first non-whitespace character in @str. */char *skip_spaces (const char *str) {while (Isspace ( *STR)) ++str;return (char *) str; /** * strim-removes leading and trailing whitespace from @s. * @s:the string to be stripped. * * Note that the first trailing whitespace are replaced with a%nul-terminator * in the given string @s. Returns A pointer To the first non-whitespace * character in @s. */char *strim (char *s) {Unsigned int Size;char *end;size = strlen (s), if (!size) return s;end = s + size-1;while (end >= s && isspace (*end)) en d--;* (end + 1) = ' + '; return skip_spaces (s);} /** * Strlen-find The length of a string * @s:the string to be sized */unsigned int strlen (const char *s) {const char *s C;for (sc = s; *sc! = '); ++sc)/* Nothing */;return sc-s;} /** * Strspn-calculate The length of the initial substring of @s which only contain letters in @accept * @s:the string To is searched * @accept: The string to search for */unsigned int strspn (const char *s, const char *accept) {const char *p; const char *a;unsigned int count = 0;for (p = s; *p = ' *a '; ++p) {for (a = accept; ++a! = '); *p) {if (= = *a) break;} if (*a = = ') ' Return count;++count;} return count;} /** * Strcspn-calculate The length of the initial substring of @s which does not contain letters in @reject * @s:the St ring to being searched * @reject: The string to avoid */unsigned int strcspn (const char *s, const CHAR *reject) {const char *p;const char *r;unsigned int count = 0;for (p = s; *p! = '); ++p) {for (R = Reject; *r! = ') '; ++R) {if (*p = = *r) return count;} ++count;} return count;} /** * Strpbrk-find The first occurrence of a set of characters * @cs: the string to being searched * @ct: the characters to Search for */char *strpbrk (const char *CS, const char *ct) {const char *SC1, *sc2;for (SC1 = cs; *sc1! = '); ++sc1) { for (SC2 = ct; *SC2! = '); ++sc2) {if (*sc1 = = *SC2) return (char *) SC1;} return NULL;} /** * Strsep-split a string into tokens * @s:the string to being searched * @ct: The characters to search for * * STRSEP () Updates @s to point after the token, ready for the next call. * * It returns empty tokens, too, behaving exactly like the libc function * of this name. In fact, it is stolen from GLIBC2 and de-fancy-fied. * Same semantics, slimmer shape. ;) */char *strsep (char **s, const char *ct) {char *sbegin = *s;char *end;if (sbegin = = NULL) return null;end = STRPBRK (Sbegin, CT); if (end) *end++ = ' + '; *s = End;return sbegin;} /** * Memset-fill a region of memory with the given value * @s:pointer to the start of the area. * @c:the byte to fill the area with * @count: the size of the area. * * Do not use memset () to access IO space, use Memset_io () instead. */void *memset (void *s, int c, unsigned int count) {char *xs = s;while (count--) *xs++ = C;return s;} /** * Memcpy-copy One area's memory to another * @dest: Where to Copy to * @src: Where to copy from * @count: the size of the area. * * You should the use of this function to access IO space, the use MEMCPY_TOIO () * or Memcpy_fromio () instead. */void *memcpy (void *dest, const void *SRC, unsigned int count) {char *tmp = dest;const char *s = src;while (count--) *tmp++ = *s++;return dest;} /** * Memmove-copy One area's memory to another * @dest: Where to Copy to * @src: Where to copy from * @count: the size of the area. * * Unlike memcpy (), Memmove () copes with overlapping areas. */void *memmove (VOID *dest, const void *SRC, unsigned int count) {char *tmp;const char *s;if (dest <= src) {tmp = Dest;s = Src;while (c ount--) *tmp++ = *s++;} else {tmp = dest;tmp + = Count;s = Src;s + count;while (count--) *--tmp = *--s;} return dest;} /** * Memcmp-compare-Areas of memory * @cs: One area of memory * @ct: Another area of memory * @count: the size of T He area. */int memcmp (const void *cs, const void *CT, unsigned int count) {const unsigned char *su1, *su2;int res = 0;for (SU1 = cs, SU2 = ct; 0 < Count; ++SU1, ++SU2, count--) if ((res = *SU1-*su2)! = 0) Break;return Res;} /** * Memscan-find a character in an area of memory. * @addr: The memory area * @c:the byte-to-search for * @size: The size of the area. * * Returns the address of the first occurrence of @c, or 1 byte past * The area if @c are not found */void *memscan (void * addr, int c, unsigned int size) {unsigned char *p = addr;while (size) {if (*p = = c) return (void *) p;p++;size--;} return (void *) p; /** * StrstR-find the first substring in a%nul terminated string * @s1: the string to is searched * @s2: The string to search for */char *strstr (const char *S1, const char *s2) {unsigned int l1, l2;l2 = strlen (s2), if (!L2) return (char *) S1;L1 = strlen (s 1); while (L1 >= L2) {l1--;if (!memcmp (S1, S2, L2)) return (char *) s1;s1++;} return NULL;} /** * Strnstr-find The first substring in a length-limited string * @s1: the string to is searched * @s2: the string to Search for * @len: The maximum number of characters to search */char *strnstr (const char *S1, const char *S2, unsigned int Len) {unsigned int l2;l2 = strlen (s2), if (!L2) return (char *) s1;while (len >= L2) {len--;if (!memcmp (S1, S2, L2)) re Turn (char *) s1;s1++;} return NULL;} /** * Memchr-find a character in an area of memory. * @s:the Memory Area * @c:the byte to search for * @n:the size of the area. * * Returns the address of the first occurrence of @c, or%null * If @c is not found */void *memchr (const void *s, int c, Unsigned int N) {const unsigned char *p = S;while (n--! = 0) {if ((unsigned char) c = = *p++) return (void *) (p-1);} return NULL;} /** * Memchr-put The string to an integer. * @s:the String * * Returns int which come from @s */int atoi (const char *s) {if (!s | | (*s! = '-') &&!isdigit (*s))) return 0; int value = 0;const char *t = s; char C = *s; do{if (IsDigit (c)) value = value*10 + C ' 0 '; if (s-t>0 &&!isdigit (*s)) Break;++s; }while ((c = *s)! = ' + '); return (*t = = '-'?-value:value);} /** * Memchr-put The string into a long int. * @s:the String * * returns long int which come from @s */long atol (const Char *s) {const char *p = skip_spaces (s); if (!p | | (*p! = '-') &&!isdigit (*p))) return 0; Long value = 0;const char *t = p; char C = *p; do{if (IsDigit (c)) value = value*10 + C ' 0 '; if (p-t>0 &&!isdigit (*p)) break;++p; }while ((c = *p)! = ' "); return (*t = = '-'?-value:value);}