3. String related functions

strlen

strcpy

strcat

strcmp

strncpy

strncat

strncmp

strstr

strtok

strerror


size_t strlen(const char *str)

#include<string.h>

·The string ends with'\0', and the strlen function returns the number of characters that appear before'\0' in the string (not including'\0').
·The character string pointed to by the parameter must end with'\0'.
·Note that the return value of the function is size_t, which is unsigned (error-prone)
·Analog implementation of the strlen function

example:
/* strlen example1 */
#include <stdio.h>
#include <string.h>
int main()
{
	const char* str1 = "abcdef";
	const char* str2 = "bbb";
	if (strlen(str2) - strlen(str1) > 0)
	{
		printf("str2>str1\n");
	}
	else
	{
		printf("srt1>str2\n");
	}
	return 0;
}

/* strlen example2 */
#include <stdio.h>
#include <string.h>

int main ()
{
   char str[50];
   int len;

   strcpy(str, "This is runoob.com");

   len = strlen(str);
   printf("|%s| 的长度是 |%d|\n", str, len);
   
   return(0);
}

Counter simulation implementation:
/* simulation of strlen function with counter */
#include <stdio.h>
//计数器实现
size_t Strlen(const char* str)
{
	size_t count = 0;
	while (*str != '\0')
	{
		++str;
		++count;
	}
	return count;
}
int main()
{
	char str[] = "This is runoob.com";
	size_t len;

	len = strlen(str);
	printf("|%s| 的长度是 |%u|\n", str, len);
	return 0;
}

Realize with recursive simulation:
/* simulation of strlen function with recursion */
#include <stdio.h>
//递归实现
size_t Strlen(const char* str)
{
	if (*str != '\0')
	{
		return Strlen(str + 1) + 1;
	}
	else
		return 0;
}
int main()
{
	char str[] = "This is runoob.com";
	size_t len;

	len = Strlen(str);
	printf("|%s| 的长度是 |%u|\n", str, len);
	return 0;
}


Use pointer address difference method to simulate and realize:
/* simulation of strlen function with indicator */
#include <stdio.h>
//指针地址差实现
size_t strlen(const char* str)
{
	const char* eos = str;
	while (*eos++);
		return (eos - str - 1);
}
int main()
{
	char str[] = "This is runoob.com";
	size_t len;

	len = strlen(str);
	printf("|%s| 的长度是 |%u|\n", str, len);
	return 0;
}
Implementation in the library:
/*strlen in lib*/


size_t __cdecl strlen (
        const char * str
        )
{
        const char *eos = str;

        while( *eos++ ) ;

        return( eos - str - 1 );
}


char * strcpy (char * dest, const char * src)

#include<string.h>

dest-points to the target array used to store the copied content.
src-the string to be copied.

example:
/* strcpy example1 */
#include <stdio.h>
#include <string.h>
 
int main()
{
   char src[40];
   char dest[100];
  
   memset(dest, '\0', sizeof(dest));
   strcpy(src, "This is runoob.com");
   strcpy(dest, src);
 
   printf("最终的目标字符串: %s\n", dest);
   
   return(0);
}

/* strcpy example2 */
#include <stdio.h>
#include <string.h>
 
int main ()
{
  char str1[]="Sample string";
  char str2[40];
  char str3[40];
  strcpy (str2,str1);
  strcpy (str3,"copy successful");
  printf ("str1: %s\nstr2: %s\nstr3: %s\n",str1,str2,str3);
  return 0;
}

Simulation implementation:
/* simulation of strcpy1*/
#include <stdio.h>
#include <string.h>
char* Strcpy(char* dest, const char* src)
{
    char * cp = dest;
	while (*src)
	{
		*cp++ = *src++;
	}
	*cp = *src;
	return dest;
}
int main()
{
	char src[40];
	char dest[100];

	memset(dest, '\0', sizeof(dest));
	Strcpy(src, "This is runoob.com");
	Strcpy(dest, src);

	printf("最终的目标字符串: %s\n", dest);

	return(0);
}


/* simulation of strcpy2*/
#include <stdio.h>
#include <string.h>
#include <assert.h>
char* Strcpy(char* dest, const char* src)
{
    char * cp = dest;
	assert(src != NULL);
	while (*cp++ = *src++);
	return dest;
}
int main()
{
	char src[40];
	char dest[100];

	memset(dest, '\0', sizeof(dest));
	Strcpy(src, "This is runoob.com");
	Strcpy(dest, src);

	printf("最终的目标字符串: %s\n", dest);

	return(0);
}

Implementation in the library:
/*strcpy in lib*/


char * __cdecl strcpy(char * dst, const char * src)
{
	char * cp = dst;
 
	while (*cp++ = *src++)
		;               /* Copy src over dst */
 
	return(dst);

}


char *strcat(char *dest, const char *src)

#include<string.h>

dest-points to the target array, which contains a C string and is large enough to hold the appended string.
src-points to the string to be appended, which will not overwrite the target string.

example:
/* strcat example */
#include <stdio.h>
#include <string.h>
 
int main ()
{
   char src[50], dest[50];
 
   strcpy(src,  "This is source");
   strcpy(dest, "This is destination");
 
   strcat(dest, src);
 
   printf("最终的目标字符串: |%s|", dest);
   
   return(0);
}

Simulation implementation:
/* simulation of strcat*/
#include <stdio.h>
#include <string.h>
#include <assert.h>
char* Strcat(char* dest, const char* src)
{
    char * cp = dest;
	/*while (*cp) 
		++cp;*/
	if (*cp)
		while (*(++cp));
	assert(src != NULL);
	while (*cp++ = *src++);
	return dest;
}
int main()
{
	char src[50], dest[50];

	strcpy(src, "This is source");
	strcpy(dest, "This is destination");

	Strcat(dest, src);

	printf("最终的目标字符串: |%s|", dest);

	return(0);
}


Implementation in the library:
/*strcat in lib*/  
char * __cdecl strcat (
        char * dst,
        const char * src
        )
{
        char * cp = dst;

        while( *cp )
                cp++;                   /* find end of dst */

        while( *cp++ = *src++ ) ;       /* Copy src to end of dst */

        return( dst );                  /* return dst */

}

int strcmp(const char *str1, const char *str2)

#include<string.h>

str1-The first string to be compared.
str2-The second string to be compared.
If the return value is <0, it means that str1 is less than str2.
If the return value> 0, it means that str2 is less than str1.
If the return value = 0, it means that str1 is equal to str2.

example:
/* strcmp example */
#include <stdio.h>
#include <string.h>
 
int main ()
{
   char str1[15];
   char str2[15];
   int ret;
 
 
   strcpy(str1, "abcdef");
   strcpy(str2, "ABCDEF");
 
   ret = strcmp(str1, str2);
 
   if(ret < 0)
   {
      printf("str1 小于 str2");
   }
   else if(ret > 0) 
   {
      printf("str2 小于 str1");
   }
   else 
   {
      printf("str1 等于 str2");
   }
   
   return(0);
}

Simulation implementation:
/* simulation of strcmp*/
#include <stdio.h>
#include <string.h>

int Strcmp(const char* src, const char* dst)
{
	while ( (*src && *dst) && *src++ == *dst++);  //*src != '\0'&& *dst != '\0'  --> *src && *dst
	if (!*src && !*dst)	return 0;
	else if (!*src) return -1;
	else if (!*dst) return 1;
	else
		return *src - *dst;
}

int main()
{
	char str1[15];
	char str2[15];
	int ret;

	strcpy(str1, "abcdef");
	strcpy(str2, "ABCDEF");

	ret = Strcmp(str1, str2);

	if (ret < 0)
	{
		printf("str1 小于 str2");
	}
	else if (ret > 0)
	{
		printf("str2 小于 str1");
	}
	else
	{
		printf("str1 等于 str2");
	}

	return(0);
}
Implementation in the library:
/*strcmp in lib*/
int __cdecl strcmp (
        const char * src,
        const char * dst
        )
{
        int ret = 0 ;

        while( ! (ret = *(unsigned char *)src - *(unsigned char *)dst) && *dst)
                ++src, ++dst;

        if ( ret < 0 )
                ret = -1 ;
        else if ( ret > 0 )
                ret = 1 ;

        return( ret );
}

char *strncpy(char *dest, const char *src, size_t n)

#include<string.h>

dest-points to the target array used to store the copied content.
src-the string to be copied.
n-The number of characters to be copied from the source.
This function returns the final copied string.

example:
/* strncpy example */  //不追加'\0'
#include <stdio.h>
#include <string.h>

int main()
{
   char src[40];
   char dest[12];
  
   memset(dest, '\0', sizeof(dest));
   strcpy(src, "This is runoob.com");
   strncpy(dest, src, 10);

   printf("最终的目标字符串: %s\n", dest);
   
   return(0);
}
Simulation implementation
/* simulation of strncpy*/  //不追加'\0'
#include <stdio.h>
#include <string.h>

char* Strncpy(char* dest, const char* src, size_t n)
{
	char* cp = dest;
	while (n--)
	{
		*cp++ = *src++;
	}
	return dest;
}

int main()
{
	char src[40];
	char dest[12];

	memset(dest, '\0', sizeof(dest));
	strcpy(src, "This is runoob.com");
	Strncpy(dest, src, 10);

	printf("最终的目标字符串: %s\n", dest);

	return(0);
}

Implementation in the library:
/*Strncpy in lib*/
char * __cdecl strncpy (
        char * dest,
        const char * source,
        size_t count
        )
{
        char *start = dest;

        while (count && (*dest++ = *source++))    /* copy string */
                count--;

        if (count)                              /* pad out with zeroes */
                while (--count)
                        *dest++ = '\0';

        return(start);
}

char *strncat(char *dest, const char *src, size_t n)

#include<string.h>

dest-points to the target array, which contains a C string and is large enough to hold the appended string, including extra null characters.
src-the string to be appended.
n-the maximum number of characters to append.
Return value:
This function returns a pointer to the final target string dest

example:
/* strncat example */  //追加'\0'
#include <stdio.h>
#include <string.h>

int main ()
{
   char src[50], dest[50];

   strcpy(src,  "This is source");
   strcpy(dest, "This is destination");

   strncat(dest, src, 15);

   printf("最终的目标字符串: |%s|", dest);
   
   return(0);
}
Simulation implementation:
/* simulation of strncat*/
#include <stdio.h>
#include <string.h>
char* Strncat(char* dest, const char* src, size_t n)
{
	char* cp = dest;
	if(*cp)
		while (*(++cp));  //如果dest第一个是\0元素,防止从从它后面开始复制
	while (n--)
	{
		if(!(*cp++ = *src++))    //防止越界写
		return dest;
	}
	*cp = '\0';
	return dest;
}

int main()
{
	char src[50], dest[50] = {0};

	strcpy(src, "This is source");
	//strcpy(dest, "This is destination");


	Strncat(dest, src, 15);

	printf("最终的目标字符串: |%s|", dest);

	return(0);
}
Implementation in the library:
/*Strncat in lib*/  //追加'\0'
char * __cdecl strncat (
        char * front,
        const char * back,
        size_t count
        )
{
        char *start = front;

        while (*front++)
                ;
        front--;

        while (count--)
                if (!(*front++ = *back++))
                        return(start);

        *front = '\0';  //追加'\0'
        return(start);
}

int strncmp(const char *str1, const char *str2, size_t n)

#include<string.h>

str1-The first string to be compared.
str2-The second string to be compared.
n-the maximum number of characters to compare.
Return value
The return value of this function is as follows:
If the return value <0, it means that str1 is less than str2.
If the return value> 0, it means that str2 is less than str1.
If the return value = 0, it means that str1 is equal to str2.

example:
/* strncmp example */
#include <stdio.h>
#include <string.h>

int main ()
{
   char str1[15];
   char str2[15];
   int ret;


   strcpy(str1, "abcdef");
   strcpy(str2, "ABCDEF");

   ret = strncmp(str1, str2, 4);

   if(ret < 0)
   {
      printf("str1 小于 str2");
   }
   else if(ret > 0) 
   {
      printf("str2 小于 str1");
   }
   else 
   {
      printf("str1 等于 str2");
   }
   
   return(0);
}
Simulation implementation:
/* simulation of strncmp1*/
#include <stdio.h>
#include <string.h>
int Strncmp(const char* str1, const char* str2, size_t n)
{
	while (n && (*str1 && *str2) && (*str1++ == *str2++)) n--;
	if (!*str1 && !*str2) return 0;
	else if (!*str1) return -1;
	else if (!*str2) return 1;
	else return *str1 - *str2;
}

int main()
{
	char str1[15];
	char str2[15];
	int ret;


	strcpy(str1, "abcdef");
	strcpy(str2, "ABCDEF");

	ret = strncmp(str1, str2, 4);

	if (ret < 0)
	{
		printf("str1 小于 str2");
	}
	else if (ret > 0)
	{
		printf("str2 小于 str1");
	}
	else
	{
		printf("str1 等于 str2");
	}

	return(0);
}
/* simulation of strncmp2*/
#include <stdio.h>
#include <string.h>
int Strncmp(const char* str1, const char* str2, size_t n)
{
	int res = 0;
	while (n && (*str1 && *str2) && !(res = *str1++ - *str2++)) n--;
	if (!n) return 0;
	if (res < 0) return -1;
	else return 1;
}

int main()
{
	char str1[15];
	char str2[15];
	int ret;


	strcpy(str1, "ABCdef");
	strcpy(str2, "ABCDEF");

	ret = strncmp(str1, str2, 3);

	if (ret < 0)
	{
		printf("str1 小于 str2");
	}
	else if (ret > 0)
	{
		printf("str2 小于 str1");
	}
	else
	{
		printf("str1 等于 str2");
	}

	return(0);
}

/* simulation of strncmp3 鲍*/
#include <stdio.h>
#include <string.h>

int Strncmp(
	const char* first,
	const char* last,
	size_t     count)
{
	assert(first != NULL);
	assert(last  != NULL);

	while (count && *first == *last)
	{
		first++,last++;
		count--;
	}
	return (int)(*first - *last);
}

int main()
{
	char str1[15];
	char str2[15];
	int ret;


	strcpy(str1, "ABCdef");
	strcpy(str2, "ABCDEF");

	ret = strncmp(str1, str2, 3);

	if (ret < 0)
	{
		printf("str1 小于 str2");
	}
	else if (ret > 0)
	{
		printf("str2 小于 str1");
	}
	else
	{
		printf("str1 等于 str2");
	}

	return(0);
}

Implementation in the library:
/*Strncmp in lib*/
int __cdecl strncmp
(
    const char *first,
    const char *last,
    size_t      count
)
{
    size_t x = 0;

    if (!count)
    {
        return 0;
    }

    /*
     * This explicit guard needed to deal correctly with boundary
     * cases: strings shorter than 4 bytes and strings longer than
     * UINT_MAX-4 bytes .
     */
    if( count >= 4 )
    {
        /* unroll by four */
        for (; x < count-4; x+=4)
        {
            first+=4;
            last +=4;

            if (*(first-4) == 0 || *(first-4) != *(last-4))
            {
                return(*(unsigned char *)(first-4) - *(unsigned char *)(last-4));
            }

            if (*(first-3) == 0 || *(first-3) != *(last-3))
            {
                return(*(unsigned char *)(first-3) - *(unsigned char *)(last-3));
            }

            if (*(first-2) == 0 || *(first-2) != *(last-2))
            {
                return(*(unsigned char *)(first-2) - *(unsigned char *)(last-2));
            }

            if (*(first-1) == 0 || *(first-1) != *(last-1))
            {
                return(*(unsigned char *)(first-1) - *(unsigned char *)(last-1));
            }
        }
    }

    /* residual loop */
    for (; x < count; x++)
    {
        if (*first == 0 || *first != *last)
        {
            return(*(unsigned char *)first - *(unsigned char *)last);
        }
        first+=1;
        last+=1;
    }

    return 0;
}


char *strstr(const char *haystack, const char *needle)

#include<string.h>

haystack-The C string to be retrieved.
needle-The small string to be searched in the haystack string.
Return value:
This function returns the position where the needle string appears for the first time in haystack, or null if it is not found.

example:
/* strstr example */
#include <stdio.h>
#include <string.h>
int main()
{
	const char haystack[20] = "RUNOOB";
	const char needle[10] = "NOOB";
	const char* ret = NULL;

	ret = strstr(haystack, needle);

	printf("子字符串是: %s\n", ret);

	return(0);
}
The prototype of the function strstr is char *strstr(char *str1, char *str2); its function is to return the position of the first occurrence of the specified string str2 in str1. Simulation implementation:
/*simulation of strstr1*/
#include <stdio.h>
#include <string.h>

char* Strstr(const char* str1, const char* str2)
{
	const char* p1 = str1;
	while (*p1++);  //p指向'\0'后面
	int length1 = p1 - str1 - 1;

	const char* p2 = str2;
	while (*p2++);  //p指向'\0'后面
	int length2 = p2 - str2 - 1;

	//while(*p2)  p2++;  //p指向'\0'
	//int length2 = p2 - str2; 

	int nums = length1 - length2 + 1;

	for (int i = 0; i < nums; ++i)
	{
		if (!strncmp(str1 + i, str2, length2))
			return (char*)(str1 + i);
	}
	return nullptr;
}

int main()
{
	char haystack[20] = "RUNOOB";
	char needle[10] = "NOOB";
	char* ret = NULL;

	ret = Strstr(haystack, needle);

	printf("子字符串是:%s\n", ret);

	return(0);
}

/*simulation of strstr2*/
#include <stdio.h>
#include <string.h>

char* Strstr(const char* str1, const char* str2)
{
	const char* p1 = str1;
	while (*p1++);  //p指向'\0'后面
	int length1 = p1 - str1 - 1;

	const char* p2 = str2;
	while (*p2++);  //p指向'\0'后面
	int length2 = p2 - str2 - 1;

	//while(*p2)  p2++;  //p指向'\0'
	//int length2 = p2 - str2; 

	int nums = length1 - length2 + 1;
	for (int i = 0; i < nums; ++i)
	{
		//if (!strncmp(str1 + i, str2, length2))
		int flag = 0;
		for (int j = 0; j < length2; ++j)
		{
			if (*(str1 + i + j) == *(str2 + j))
				flag = 1;
			else
				flag = 0;
		}
		if(flag)
			return (char*)(str1 + i);
	}
	return nullptr;
}

int main()
{
	char haystack[20] = "RUNOOB";
	char needle[10] = "NOOB";
	char* ret = nullptr;

	ret = Strstr(haystack, needle);

	printf("子字符串是:%s\n", ret);

	return(0);
}

/*strstr in lib*/



char * strtok ( char * str, const char * delimiters );

#include<string.h>

The C library function char *strtok(char *>str, const char *delim) separates the string str as a set of strings, and delim as the delimiter

example:
/* strtok example1 */
#include <stdio.h>
#include <string.h>

int main ()
{
  char str[] ="- This, a sample string.";
  char * pch;
  printf ("Splitting string \"%s\" into tokens:\n",str);
  pch = strtok (str," ,.-");
  while (pch != NULL)
  {
    printf ("%s\n",pch);
    pch = strtok (NULL, " ,.-");
  }
  return 0;
}
/* strtok example2 */
#include <string.h>
#include <stdio.h>
 
int main () {
   char str[80] = "This is - www.runoob.com - website";
   const char s[2] = "-";
   char *token;
   
   /* 获取第一个子字符串 */
   token = strtok(str, s);
   
   /* 继续获取其他的子字符串 */
   while( token != NULL ) {
      printf( "%s\n", token );
    
      token = strtok(NULL, s);
   }
   
   return(0);
}
The simulation is achieved:
/*simulation of strtok*/


Implementation in the library:
/*strtok in lib  1*/
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
#include <string.h>

char* strtok(char *s, const char *delim)
{
  const char *spanp;
  int c, sc;
  char *tok;
  static char *last;

  if (s == NULL && (s = last) == NULL)
    return (NULL);
  /*
   * Skip (span) leading delimiters (s += strspn(s, delim), sort of).
   * 跳过字符串首部的分隔符
   */
 cont:
  c = *s++;
  for (spanp = delim; (sc = *spanp++) != 0;) {
    if (c == sc)
      goto cont;
  }
  
  /*
   *分割符后面没有字符串了
   */
  if (c == 0) {                 /* no non-delimiter characters */
    last = NULL;
    return (NULL);
  }
  tok = s - 1;    /*分割符后面还有字符串,将tok指向字符串首部(不包括分隔符)*/

  /*
   * Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
   * Note that delim must have one NUL; we stop if we see that, too.
   * 循环字符串中的字符,直到找到分隔符或者结束符,并替换成结束符
   */
  for (;;) {
    c = *s++;
    spanp = delim;
    /*
     *判断字符串中的某字符是否是分割符中的字符
     *如果是,将分隔符替换成结束符并返回tok;
     *如果不是,继续判断下一个字符
     */
    do {
      if ((sc = *spanp++) == c) {
        if (c == 0)
          s = NULL;
        else
          s[-1] = 0;
        last = s;
        return (tok);
      }
    } while (sc != 0);
  }
  /* NOTREACHED */
}
/*strtok in lib  2*/
#ifdef _SECURE_VERSION
#define _TOKEN *context
#else  /* _SECURE_VERSION */
#define _TOKEN ptd->_token
#endif  /* _SECURE_VERSION */
 
#ifdef _SECURE_VERSION
char * __cdecl strtok_s (
        char * string,
        const char * control,
        char ** context
        )
#else  /* _SECURE_VERSION */
char * __cdecl strtok (
        char * string,
        const char * control
        )
#endif  /* _SECURE_VERSION */
{
        unsigned char *str;
        const unsigned char *ctrl = control;
 
        unsigned char map[32];
        int count;
 
#ifdef _SECURE_VERSION
 
        /* validation section */
        _VALIDATE_RETURN(context != NULL, EINVAL, NULL);
        _VALIDATE_RETURN(string != NULL || *context != NULL, EINVAL, NULL);
        _VALIDATE_RETURN(control != NULL, EINVAL, NULL);
 
        /* no static storage is needed for the secure version */
 
#else  /* _SECURE_VERSION */
 
        _ptiddata ptd = _getptd();
 
#endif  /* _SECURE_VERSION */
 
        /* Clear control map */
        for (count = 0; count < 32; count++)
                map[count] = 0;
 
        /* Set bits in delimiter table */
        do {
                map[*ctrl >> 3] |= (1 << (*ctrl & 7));
        } while (*ctrl++);
 
        /* Initialize str */
 
        /* If string is NULL, set str to the saved
         * pointer (i.e., continue breaking tokens out of the string
         * from the last strtok call) */
        if (string)
                str = string;
        else
                str = _TOKEN;
 
        /* Find beginning of token (skip over leading delimiters). Note that
         * there is no token iff this loop sets str to point to the terminal
         * null (*str == '\0') */
        while ( (map[*str >> 3] & (1 << (*str & 7))) && *str )
                str++;
 
        string = str;
 
        /* Find the end of the token. If it is not the end of the string,
         * put a null there. */
        for ( ; *str ; str++ )
                if ( map[*str >> 3] & (1 << (*str & 7)) ) {
                        *str++ = '\0';
                        break;
                }
 
        /* Update nextoken (or the corresponding field in the per-thread data
         * structure */
        _TOKEN = str;
 
        /* Determine if a token has been found. */
        if ( string == str )
                return NULL;
        else
                return string;
}


strerror

#include<string.h>

The C library function char *strerror(int errnum) searches for the error number errnum from the internal array and returns a pointer to the error message string. The error string generated by strerror depends on the development platform and compiler.
Declaration
The following is the declaration for the strerror() function.
char *strerror(int errnum)
parameter
errnum-error number, usually errno.
Return value
This function returns a pointer to the error string, which describes the error errnum.

example:
/* strerror example */
#include <stdio.h>
#include <string.h>
#include <errno.h>

int main ()
{
   FILE *fp;

   fp = fopen("file.txt","r");
   if( fp == NULL ) 
   {
      printf("Error: %s\n", strerror(errno));
   }
   
  return(0);
}

Guess you like

Origin blog.csdn.net/qq_43808700/article/details/112706562