[置顶] c/c++字符串处理函数

       C语言处理字符串极为不便,幸好库函数提供了还算丰富的处理字符串的函数。有一些函数我们平时不大用的到,不过了解一下总是好的,知道有这么个东西,下次要用的时候再去查一下手册就好了。

        这里介绍的函数主要有:strcat, strcmp, strcasecmp, strcpy, strdup, strlen, strchr, strrchr, strstr, strpbrk, strspn, strcspn, strtok. 在本章的最后还会给出这些库函数的具体实现,以应付一些企业的面试。

       文章共分四个部分,第一部分直接列出了常用的字符串处理函数,由于这些都是大家平时接触的比较多的,在此不再多说;第二部分介绍了不太常用的字符串处理函数,并给出了具体示例,很多函数看名字很难猜到它的具体作用,但是一个小小的例子就能解释得很清楚;第三部分给出了这些函数的具体实现,大部分参考网上个人认为已经不错的实现,部分是查看glibc源代码后,简化得来的程序;第四部分作者非常道德的给出了参考资料。


常用的字符串处理函数:


char *strcat(char *s1, const char *s2);

char *strncat(char *s1, const char *s2);

int strcmp(const char *s1, const char *s2);
int strncmp(const char *s1, const char *s2, size_t length);

int strcasecmp(const char *s1, const char *s2);
int strncasecmp(const char *s1, const char *s2, size_t length);

char *strcpy(char *s1, const char *s2);
char *strncpy(char *s1, const char *s2, size_t length);

size_t strlen(const char *s1);


不太常用的字符串处理函数:


//the strdup() function allocates memory and copies into it the string addressed s1. including the terminating null character. 

//It is the use's responsibility to free the allocated storage by calling free()

char *strdup(const char *s1);

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char* argv[])
{
	char str[] = "this is a example";
	char *p = NULL;
	if ((p = strdup(str)) != NULL)
	{
		printf("strlen(p) = %d  \t sizeof(p) = %d\n", strlen(p), sizeof(p));
		printf("strlen(str) = %d\t sizeof(str) = %d\n", strlen(str), sizeof(str));
		if ( p == str )
		{
			puts("p == str");
		}
		else
		{
			puts("p != str");
		}
	}
	free(p);
	p = NULL;
	return 0;
}
output:

lalor@ubuntu:~/temp$ ./a.out 
strlen(p) = 17   sizeof(p) = 4
strlen(str) = 17 sizeof(str) = 18
p != str


//locate first occurrence of character in string

char *strchr(const char *s1, int c); 

#include <stdio.h>
#include <string.h>

int main(int argc, char* argv[])
{
	char str[] = "This is a sample string";
	char *pch;
	pch = strchr(str, 's');
	while (pch != NULL)
	{
		printf("found at %d\n", pch - str + 1);
		pch = strchr(pch + 1, 's');
	}
	return 0;
}
output:
lalor@ubuntu:~/temp$ ./a.out 
found at 4
found at 7
found at 11
found at 18


// locate last occurrence of character in string

char *strrchr(const char *s1, int c);

#include <stdio.h>
#include <string.h>

int main(int argc, char* argv[])
{
	char str[] = "This is a sample string";
	char *pch;
	pch = strrchr(str, 's');
	printf("found at %d\n", pch - str + 1);
	return 0;
}
output:
lalor@ubuntu:~/temp$ ./a.out 
found at 18


//locate substring
char *strstr(const char *s1, const char *s2);

#include <stdio.h>
#include <string.h>

int main(int argc, char* argv[])
{
	char str[] = "This is a simple string. It's really a simple string";
	char *pch = NULL;
	pch = strstr(str, "simple");
	while (pch != NULL)
	{
		printf("found %d\n", pch - str + 1);
		pch = strstr(pch+1, "simple");
	}
	return 0;
}
output:
lalor@ubuntu:~/temp$ ./a.out 
found 11
found 40


//return a pointer to the first occurrence in s1 of any of characters that are
//part of s2 ,or a null pointer if there are no matcher.
char *strpbrk(const char* s1, const char *s2);

#include <stdio.h>
#include <string.h>

int main(int argc, char* argv[])
{
	char str[] = "This is a simple string.";
	char key[] = "aeiou";
	char *pch = NULL;
	printf("Vowels in '%s' : ", str);
	pch = strpbrk(str, key);
	while (pch != NULL)
	{
		printf("%c  ", *pch);
		pch = strpbrk(pch + 1, key);
	}
	printf("\n");
	return 0;
}
output:
lalor@ubuntu:~/temp$ ./a.out 
Vowels in 'This is a simple string.' : i  i  a  i  e  i 

/*

 * scans s1 for the first occurrence of any of the characters that are part of
 * s2. return the number of characters of s1 read before this first occurrence
 */

size_t strcspn(const char *s1, const char *s2);

#include <stdio.h>
#include <string.h>

int main ()
{
  char str[] = "fcba73";
  char keys[] = "1234567890";
  int i;
  i = strcspn (str,keys);
  printf ("The first number in str is at position %d.\n",i+1);
  return 0;
}
output:
lalor@ubuntu:~/temp$ ./a.out 
The first number in str is at position 5.


// return the length of the initial portion of s1 containing only characters
// that appear in s2
size_t strspn(const char *s1, const char *s2);


#include <stdio.h>
#include <string.h>

int main ()
{
  int i;
  char strtext[] = "129th";
  char cset[] = "1234567890";

  i = strspn (strtext,cset);
  printf ("The length of initial number is %d.\n",i);
  return 0;
}
output:

lalor@ubuntu:~/temp$ ./a.out 
The length of initial number is 3.

//split string into tokens

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

#include <stdio.h>
#include <string.h>

int main(int argc, char* argv[])
{
	char str[] = " - this, a sample string.";
	char *pch = NULL;
	printf("Splitting string \" %s \" into tokens:\n", str);
	pch = strtok(str, " ,.-");//first call
	while (pch != NULL)
	{
		printf("%s\n", pch);
		pch = strtok(NULL, " ,.-");//later call, the second time use strtok, first argument must be NULL
	}
	//note: strtok will modify the first string
	printf("strlen(str) = %d\tsizeof(str)/sizeof(char) = %d\n", strlen(str),
			sizeof(str)/sizeof(char));
	return 0;
}
output:

lalor@ubuntu:~/temp$ ./a.out 
Splitting string "  - this, a sample string. " into tokens:
this
a
sample
string
strlen(str) = 7 sizeof(str)/sizeof(char) = 26


函数源码:

char *strcat(char *s1, const char *s2);

char* strcat(char *strDes, const char *strSrc)

{
	assert((strDes != NULL) && (strSrc != NULL));
	char *address = strDes;

	while (*strDes != '\0') 
	{
		++strDes;
	}

	while ((*strDes++ = *strSrc++) != '\0') 
	{
		NULL;
	}
	return address;
}


char *strncat(char *s1, const char *s2);
char* strncat(char *dest, const char*str, size_t n)
{
	size_t dest_len = strlen(dest);
	size_t i;
	for (i = 0; i < n && src[i] != '\0'; i++) 
	{
		dest[dest_len + i] = src[i];
	}
	dest[dest_len + i] = '\0';

	return dest;
}


int strcmp(const char *s1, const char *s2);
int strcmp(const char *s, const char *t)
{
	assert((s != NULL) && (t != NULL))
	while (*s && *t && *s == *t) 
	{
		s++;
		t++;
	}
	return (*s - *t);
}



int strncmp(const char *s1, const char *s2, size_t length);

int strcmp(const char *s, const char *t, size_t n)
{
	assert((s != NULL) && (t != NULL) && n > 0)
	while (*s && *t && *s == *t && n--) 
	{
		s++;
		t++;
	}
	return (*s - *t);
}


int strcasecmp(const char *s1, const char *s2);

int strcmp(const char *s, const char *t)
{
	assert((s != NULL) && (t != NULL))
		char c1, c2;
	while (*s && *t ) 
	{
		c1 = TOLOWER(*s);
		c2 = TOLOWER(*t);
		if (c1 != c2) 
		{
			break;
		}
		else
		{
			s++;
			t++;
		}
	}
	return (c1 - c2);
}



int strncasecmp(const char *s1, const char *s2, size_t length);

int strcmp(const char *s, const char *t, size_t n)
{
	assert((s != NULL) && (t != NULL) && n > 0)
		char c1, c2;
	while (*s && *t && n--) 
	{
		c1 = TOLOWER(*s);
		c2 = TOLOWER(*t);
		if (c1 != c2) 
		{
			break;
		}
		else
		{
			s++;
			t++;
		}
	}
	return (c1 - c2);
}



char *strcpy(char *s1, const char *s2);


char *strncpy(char *s1, const char *s2, size_t length);
The strncpy() function is similar, except that at most n bytes  of  src
 are  copied.  Warning: If there is no null byte among the first n bytes
of src, the string placed in dest will not be null-terminated.



       If the length of src is less than n, strncpy() pads  the  remainder  of
       dest with null bytes.

char *   strncpy(char *dest, const char *src, size_t n)
           {
               size_t i;


               for (i = 0; i < n && src[i] != '\0'; i++)
                   dest[i] = src[i];
               for ( ; i < n; i++)
                   dest[i] = '\0';

               return dest;
           }


size_t strlen(const char *s1);
int strlen(const char *str)
{
	assert(str != NULL);
	int len = 0;

	while (*str++ != '\0') 
	{
		len++;
	}
	return len;
}



char *strdup(const char *s1);
/* Duplicate S, returning an identical malloc'd string.  */
char *
__strdup (const char *s)
{
  size_t len = strlen (s) + 1;
  void *new = malloc (len);

  if (new == NULL)
    return NULL;

  return (char *) memcpy (new, s, len);
}


char *strchr(const char *s1, int c); 
char * strchr(const char *str, int c)
{
	assert(str != NULL);
	for ( ; *str != (char)c; ++str)
	{
		if (*str == '\0') 
		{
			return NULL;
		}
	}
	return str;
}



char *strrchr(const char *s1, int c); 重复使用strchr,直至找到c的最后一次出现
/* Find the last occurrence of C in S.  */
char *
strrchr (const char *s, int c)
{
  register const char *found, *p;

  c = (unsigned char) c;

  /* Since strchr is fast, we use it rather than the obvious loop.  */

  if (c == '\0')
    return strchr (s, '\0');

  found = NULL;
  while ((p = strchr (s, c)) != NULL)
    {
      found = p;
      s = p + 1;
    }

  return (char *) found;
}

char *strstr(const char *s1, const char *s2);


char *strpbrk(const char* s1, const char *s2);
/* Find the first occurrence in S of any character in ACCEPT.  */
char *
strpbrk (s, accept)
     const char *s;
     const char *accept;
{
  while (*s != '\0')
    {
      const char *a = accept;
      while (*a != '\0')
	if (*a++ == *s)
	  return (char *) s;
      ++s;
    }

  return NULL;
}

size_t strcspn(const char *s1, const char *s2); //实现非常简单,又好理解,cool

/* Return the length of the maximum initial segment of S
   which contains no characters from REJECT.  */
size_t
strcspn (s, reject)
     const char *s;
     const char *reject;
{
  size_t count = 0;

  while (*s != '\0')
    if (strchr (reject, *s++) == NULL)
      ++count;
    else
      return count;

  return count;
}


size_t strspn(const char *s1, const char *s2);//为什么不像strcspn一样,用strchr来实现……
/* Return the length of the maximum initial segment
   of S which contains only characters in ACCEPT.  */
size_t
strspn (s, accept)
     const char *s;
     const char *accept;
{
  const char *p;
  const char *a;
  size_t count = 0;

  for (p = s; *p != '\0'; ++p)
    {
      for (a = accept; *a != '\0'; ++a)
	if (*p == *a)
	  break;
      if (*a == '\0')
	return count;
      else
	++count;
    }

  return count;
}

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


参考资料:

1.c语言手册http://www.cplusplus.com/reference/clibrary/cstring/strcmp/

2. glibc源代码,下载地址:ftp://ftp.gnu.org/gnu/glibc

3. 周磊的整理的面试笔试题目http://www.cnblogs.com/v-July-v/

你可能感兴趣的:(String,ubuntu,null,character,output,returning)