天天看點

【C語言】常用字元串函數和記憶體函數的實作

  • strlen函數 常用于計算字元串中的字元個數
//my_strlen的實作
int my_strlen(const char*str){
	assert(str != null);
	int len = 0;
	while (*str != '\0'){
		++len;
		++str;
	}
	return len;
}
int main(){
		//char*p1 = "hello world"; //兩種字元串指派方式 
		//printf("%d\n", strlen(p1));
		char p2[] = "hello world";
		printf("%d\n", my_strlen(p2));
		system("pause");
		return 0;
}
           
  • strcpy函數 常用于字元串的拷貝
//my_strcpy的實作
char* my_strcpy(char*dst, const char*src){
	assert(dst != NULL);
	assert(src != NULL);
	char*ret = dst;
	while (*src != '\0'){
		*dst = *src;
		++src;
		++dst;
	}
	*dst = '\0';
	return ret;
}
int main(){
	char p1[] = "hello";
	char p2[] = "world";
	//strcpy(p2, p1);//把p1的字元串拷貝到p2上
	//printf("%s\n", p2);
	my_strcpy(p2, p1);
	printf("%s\n", p2);
	system("pause");
	return 0;
}

           
  • strcat函數 常用于字元串追加拷貝
//my_strcat的實作
char* my_strcat(char* dst, const char*src){
	assert(dst&&src);
	char* ret = dst;
	while (*dst != '\0'){
		++dst;
	}
	while (*dst++ = *src++);
	return ret;
}
int main(){
		char p1[11] = "hello";
		char*p2 = "world";
		my_strcat(p1, p2);
		printf("%s\n",p1);
		system("pause");
		return 0;
}
           
  • strcmp函數 常用于字元串比較大小(比較SACII碼)
//my_strcmp的實作
int my_strcmp(const char* str1, const char* str2){
	assert(str1&&str2);
	int ret = 0;
	unsigned char* s1 = (unsigned char*)str1;
	unsigned char* s2 = (unsigned char*)str2;
	while (*s1 && *s2){
		if (*s1 > *s2)
		{
			return 1;
		}else if (*s1 < *s2)
		{
			return -1;
		}
		else{
			++s1;
			++s2;
		}
	}
	if (*s1 == '\0'&& *s2 == '\0')
	{  
		return 0;
	}else if (*s1 == '\0')
	{
		return -1;
	}
	else{
		return 1;
	}
	return ret;
}
int main(){
	char* p1 = "hello";
	char* p2 = "world";
	printf("%d\n", my_strcmp(p1, p2));
	system("pause");
	return 0;
}
           
  • strstr函數 用于判斷str2是否為str1的子串
//my_strstr的實作
const char* my_strstr(const char*src,const char*sub){
	assert(src && sub);
	const char* srci = src;
	const char* subi = sub;
	while (*srci != '\0'){
		while (*srci == *subi && *subi != '\0')
		{
			++srci;
			++subi;
		}
		if (*subi == '\0')
		{
			return src;
		}
		else
		{
			subi = sub;
			++src;
			srci = src;
		}
	}
	return NULL;
}
int main(){
	char* p1 = "abcde"; //判斷是否是旋轉串
	char* p2 = "cdeba";
	char p3[11];
	strcpy(p3, p1);
	strcat(p3, p2);
	if (my_strstr(p3,p2)!= NULL)
	{
		printf("是旋轉串\n");
	}
	else{
		printf("不是旋轉串\n");
	}
	char* p4 = "aaaaa";
	char* p5 = "aabb";
	if (my_strstr(p4, p5) != NULL)
	{
		printf("是旋轉串\n");
	}
	else{
		printf("不是旋轉串\n");
	}
	system("pause");
	return 0;
}
           
  • memcpy函數 常用于記憶體拷貝
//my_memcpy的實作
void* my_memcpy(void* dst, const void* src, size_t num){  //注意是void* 因為可能是任意類型
	assert(dst && src);
	char* str_dst = (char*)dst;
	char* str_src = (char*)src;
	for (size_t i = 0; i < num; ++i){
		str_dst[i] = str_src[i];
	}
	return dst;
}
int main(){
	int a1[10] = { 1, 2, 3, 4, 5 };
	int a2[10];
	my_memcpy(a2, a1, 10 * sizeof(int));
	for (int i = 0; i < 10;i++)
	{
		printf("%d ", a2[i]);
	}
	printf("\n");
	system("pause");
	return 0;
}
           
  • memmove函數 常用于記憶體拷貝中記憶體重疊問題
//my_memmove的實作
void* my_memmove(void* dst,const void* src,size_t num){
	assert(dst && src);
	char* str_dst = (char*)dst;
	char* str_src = (char*)src;
	if (str_src < str_dst && dst < str_src+num) //後重疊 從前往後拷貝
	{
		for (int i = num - 1; i >= 0; --i)
		{
			str_dst[i] = str_src[i];
		}
	}
	else{  //前重疊 不重疊 從前往後拷貝
		for (int i = 0; i < num; ++i)
		{
			str_dst[i] = str_src[i];
		}
	}
	return dst;
}
int main(){
	int a[10] = { 1, 2, 3, 4, 5 };
	my_memmove(a + 3, a, 5 * sizeof(int));
	for (size_t i = 0; i < 10;++i)
	{
		printf("%d ", a[i]);
	}
	printf("\n");
	system("pause");
	return 0;
}
           

繼續閱讀