헤헤 오늘 이 시리즈가 나오네요.
목차
1. 문자열 처리 기능
위의 내용은 몇 가지 일반적인 문자열 처리 함수입니다. 시뮬레이션 구현의 목적은 나중에 이러한 함수를 사용할 수 없을 때 주로 수행 방법을 배우기 위해 직접 작성하는 것입니다.
1. strlen의 세 가지 형태
1. 카운터
#define _CRT_SECURE_NO_WARNINGS 1
//计数器
#include<stdio.h>
#include<assert.h>
int my_strlen(const char* dest) {
int count = 0;
assert(dest);
while (*dest++) {
count++;
}
return count;
}
int main() {
char arr[] = "hello";
printf("%d",my_strlen(arr));
return 0;
}
2. 재귀
#define _CRT_SECURE_NO_WARNINGS 1
//递归
#include<stdio.h>
#include<assert.h>
int my_strlen(const char* dest) {
assert(dest);
if (!* dest)
return 0;
return 1 + my_strlen( dest + 1);
}
int main() {
char arr[] = "hello";
printf("%d", my_strlen(arr));
return 0;
}
3. 포인터 - 포인터
#define _CRT_SECURE_NO_WARNINGS 1
//指针-指针
#include<stdio.h>
#include<assert.h>
int my_strlen(const char* dest) {
assert(dest);
const char* p = dest;
while (*p) {
p++;
}
return p - dest;
}
int main() {
char arr[] = "hello";
printf("%d", my_strlen(arr));
return 0;
}
2. strcmp 시뮬레이션 구현
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>
int my_strcmp(const char* arr1, const char* arr2) {
assert(arr1 && arr2);
while (*arr1 == *arr2 ) {
arr1++;
arr2++;
if(*arr2=='\0')
return 0;
}
return *arr1 - *arr2;
}
int main() {
char arr1[20] = "hello ";
char arr2[] = "world";
int ret=my_strcmp(arr1, arr2);
if (ret == 0) {
printf("arr1=arr2");
}
if (ret < 0) {
printf("arr1<arr2");
}
if (ret > 0) {
printf("arr1>arr2");
}
return 0;
}
3. strcat 시뮬레이션 구현
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>
char* my_strcat(char* dest, const char* res) {
assert(dest && res);
char* p = dest;
while (*dest) {
dest++;
}
while (*dest++=*res++) {
;
}
return p;
}
int main() {
char arr1[20] = "hello ";
char arr2[] = "world ";
printf("%s\n", my_strcat(arr1, arr2));
return 0;
}
4. strcpy 시뮬레이션 구현
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>
char* my_strcpy(char* dest,char * src) {
assert(dest && src);
char* p = dest;
while (*dest++ = *src++);
return p;
}
int main() {
char arr1[20] = "hello ";
char arr2[] = "world";
printf("%s\n",my_strcpy(arr1, arr2) );
return 0;
}
5. strstr 시뮬레이션 구현
#define _CRT_SECURE_NO_WARNINGS 1
//模拟实现strstr函数
//在arr1中找是否包含arr2数组
#include<stdio.h>
#include<assert.h>
char* my_strstr(const char* str1, const char* str2) {
assert(str1 && str2);
const char* s1 = NULL;
const char* s2 = NULL;
//如果*str2=0;则需要返回str1的地址,所以str1的地址不能变
char* cp = str1;
if (*str2 == '\0') {
//由于我定义的是const类型的,所以返回时需要强制转换为char*类型
return (char*)str1;
}
while (*cp) {
s1 = cp;
s2 = str2;
while (*s1 && *s2 && (*s1 == *s2)) {
s1++;
s2++;
}
//这里必定是由上面的while中跳出来的,因为上面已经筛选过了,当*s2结束,返回当前cp的地址
if (*s2 == '\0')
return (char*)cp;
cp++;
}
//要么是找不到,*s2为0,程序直接结束,要么也是找不到,直到*cp为0,返回空指针,要么因为*s1为0,返回空指针
return NULL;
}
int main() {
char arr1[] = "abdjkhgio";
char arr2[] = "jk";
char* ret = my_strstr(arr1, arr2);
if (ret == NULL) {
printf("No found!");
}
else {
printf("%s", ret);
}
return 0;
}
6. strtok 구현
#define _CRT_SECURE_NO_WARNINGS 1
//strtok函数实现
#include<stdio.h>
#include<string.h>
int main() {
char arr[] = "[email protected]";
char* p = "@.";
char tmp[20] = {0};
strcpy(tmp, arr);
char* ret = NULL;
//strtok的返回值是遇到标志的地址,所以之后都是从null开始,函数将标志改为了\0
for (ret = strtok(tmp, p); ret; ret = strtok(NULL, p)) {
printf("%s\n", ret);
}
return 0;
}
2. 메모리 처리 기능
1. memcpy 시뮬레이션 및 구현
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>
//num指的是字节长度
void* my_memcpy(void* dest, const void* src, size_t num) {
void* ret = dest;
assert(dest && src);
//这个函数是一个字节一个字节的传,为了能让多种数据都能使用该函数,强制转换为char*类型
while (num--) {
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
//*(char*)dest++=*(char*)src++;
//这种方法是错的 ,解引用强制转换了之后,在进行++操作时,强制转换的作用已经不存在了
}
return ret;
}
int main() {
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
int arr2[10] = { 0 };
//arr2要够长,不然容易栈溢出。
my_memcpy(arr2, arr1, 20);
for(int i=0;i<5;i++)
printf("%d\n", *(arr2+i));
return 0;
}
2. memmove 구현 시뮬레이션
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>
void* my_memmove(void* dest, const void* src, size_t num) {
void* ret = dest;
assert(dest && src);
if (dest < src) {
while (num--) {
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
}
else {
while (num--) {
*((char*)dest + num) = *((char*)src + num);
}
}
return ret;
}
int main() {
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
my_memmove(arr1 + 2, arr1, 20);
return 0;
}
지침:
memcpy 함수는 겹치지 않는 메모리를 복사해야 합니다.
memmove 함수는 메모리 중복을 처리할 수 있습니다.
C 언어의 요구 사항에 따라 memcpy는 겹치지 않는 메모리만 복사할 수 있지만 VS에서는 겹치는 메모리를 복사할 수 있습니다.