镜缘浮影 小人本住在 苏州的城外 家里有屋又有田 生活乐无边

那些年我们一起忘掉的C (十三).字符串运算

2016-11-24
wilmosfang
c
原文地址 http://soft.dog/2016/11/24/c-basic-13/

前言

熟练运用字符型指针可以灵活操作字符串


概要


实现基础的字符串操作函数

写一个函数实现strcpy/strncpy的功能:

char *mystrcpy(char *s1,char *s2); char *mystrncpy(char *s1,char *s2,int n);

写一个函数实现strcmp/strncmp的功能:

int mystrcmp(char *s1,char *s2); int mystrncmp(char *s1,char *s2,int n);

写一个函数实现strstr的功能:

char *mystrstr(char *s1,char *s2);

代码注解

#include <stdio.h>
#define LENGTH 20

int mystrcmp(char *s1,char *s2)
{
	for(;*s1 != '\0' || *s2 !='\0';s2++,s1++) //使用指针遍历两个字符串,只要存在有一个字符串还没结束就继续后移
	{
		if (*s1 > *s2) return 1; //如果第一个字符串中当前字符比第二个字符串中的当前字符大(以ASCII码值为依据),就返回1
		else if (*s1 < *s2) return -1; //如果第一个字符串中当前字符比第二个字符串中的当前字符小(以ASCII码值为依据),就返回-1
	}
	return 0; //如果直到最后也没有分出大小,就返回0,表示相等
}

int mystrncmp(char *s1,char *s2,int n) //相较于mystrcmp,这个函数限定了比较的个数
{
	int i; //定义一个整型变量进行计数
	for(i=0;(*s1 != '\0' || *s2 !='\0') && i<n ;s2++,s1++,i++) //使用指针遍历两个字符串,只要存在有一个字符串还没结束并且还没超过限定的比较次数就继续后移
	{
		if (*s1 > *s2) return 1; //如果第一个字符串中当前字符比第二个字符串中的当前字符大(以ASCII码值为依据),就返回1
		else if (*s1 < *s2) return -1;//如果第一个字符串中当前字符比第二个字符串中的当前字符小(以ASCII码值为依据),就返回-1
	}
	return 0;//如果直到最后也没有分出大小,就返回0,表示相等
}

char *mystrcpy(char *s1,char *s2)
{
	char *p=s1; //将第一个字符串的首地址进行保存
	for(;*s2 !='\0';s2++,s1++)	*s1=*s2; //如果第二个字符串还没结束,就依次将第二个字符串中的每个字符复制给第一个
	*s1='\0'; //最后给第一个字符串加上结束符
	return p; //将第一个字符串的首地址返回
}

char *mystrncpy(char *s1,char *s2,int n)
{
	char *p=s1; //将第一个字符串的首地址进行保存
	int i; //定义一个整型变量进行计数
	for(i=0;*s2 !='\0' && i < n ;s1++,s2++,i++) *s1=*s2; //如果第二个字符串还没结束并且也没超过限定的抽取次数,就依次将第二个字符串中的每个字符复制给第一个
	*s1='\0'; //最后给第一个字符串加上结束符
	return p; //将第一个字符串的首地址返回
}

char *mystrstr(char *s1,char *s2)
{
	char *p2,*p1; //定义两个字符型指针进行比较操作
	for(;*s1 != '\0';s1++) //如果第一个字符串还没结束,就逐个遍历
	{
		for(p1=s1,p2=s2; ;p2++,p1++) //将定义的两个指针分别指向两个起始位置,同步后移,注意,s1的位置是在每轮大循环的过程中依次后移的
		{
			if (*p2 == '\0') return s1;  //比较到了第二个字符串结尾,就返回s1指的地址,意味着将第二个字符串遍历完了,都没找到不同
		    if (*p2 != *p1) break;	//如果两个字符不同就跳出,进行下一轮大循环
		}
	}
	return NULL; //直到最后也没找到这个位置就返回一个空指针,如果找到了位置就会反馈出找到的s1位置
}


void main()
{		
	char str[2*LENGTH],st[LENGTH];  //定义两个字符型数组,来存储输入的字符串
	printf("please input two string (less then %d length):\n",LENGTH);
	scanf("%s%s",str,st); //将输入分别存放到str与st数组中
	printf("the first string is :%s\nthe second string is :%s\n",str,st); 
	printf("the two string mystrcmp resault is : %d\n",mystrcmp(str,st));
	printf("the two string mystrncmp with 3 resault is : %d\n",mystrncmp(str,st,3));
	printf("the two string mystrstr resault is : %s\n",mystrstr(str,st));
	printf("the two string mystrcpy resault is : %s\n",mystrcpy(str,st));
	printf("the two string mystrncpy which 3 resault is : %s\n",mystrncpy(str,st,3));	
}

思路

mystrcmp/mystrncmp/mystrcpy/mystrncpy 思路比较简单,就是逐一比较逐一复制

mystrstr 相对复杂,从头开始逐一遍历第一个字符串的过程中,要保存当前位置,从当前位置开始逐一与第二个字符串相进行比较,如果完全包含则返回之前保存的位置,否则从第一个字符串的下一个位置开始比较,直到找到正确位置并且返回地址值或遍历完第一个字符串然后返回空值

基础知识点

  • 指针的用法
  • 指针作为函数参数
  • 函数的返回值
原文地址 http://soft.dog/2016/11/24/c-basic-13/

评论