strlen

计算字符串长度

size_t strlen(const char *str);
  • 字符串以'\0'作为结束标志, strlen函数返回的是在'\0'之前出现的字符个数(不包含'\0')
  • 参数指向的字符串必须以'\0'结束
  • 函数的返回值为size_t, 是无符号的
// 模拟实现
int my_strlen(const char *str) {
	if (*str == '\0') {
		return 0;
	}
	else {
		return my_strlen(str + 1) + 1;
	}
}

strcpy

把src地址开始且含有NULL结束的字符串复制到以dest开始的地址空间

char *strcpy(char *dest, const char *src);
  • 源字符串必须以'\0'结尾
  • 会将源字符串的'\0'拷贝到目标空间
  • 目标空间必须足够大, 以确保能够存放源字符串
  • 目标空间必须可变
  • 返回指向dest的指针
// 模拟实现
char *my_strcpy(char *dest, const char *src) {
	char *ret = dest;
	if (dest != NULL || src != NULL) {
		while ((*dest++ = *src++) != '\0') {
			;
		}
	}
	return ret;
}

strcat

把src所指向的字符串复制到dest所指向的字符串后面(删除*dest末尾的'\0')

char *strcat(char *dest, const char *src);
  • 源字符串必须以'\0'结尾
  • 目标空间必须足够大, 能容纳下源字符串的内容
  • 目标空间必须可变
  • 返回指向dest的指针
// 模拟实现
char *my_strcat(char *dest, const char *src) {
	char *ret = dest;
	if (dest != NULL || src != NULL) {
		while (*ret) {
			ret++;
		}
		while ((*ret++ = *src++) != '\0') {
			;
		}
	}
	return ret;
}

strcmp

比较字符串str1与str2是否相同

int strcmp(const char *str1, const char *str2);
  • 第一个字符串大于第二个字符串, 返回大于0的数字
  • 第一个字符串等于第二个字符串, 返回0
  • 第一个字符串小于第二个字符串, 返回小于0的数字
// 模拟实现
int my_strcmp(const char *str1, const char *str2) {
	assert(str1 != NULL);
	assert(str2 != NULL);
	while (*str1 && *str2 && (*str1 == *str2)) {
		str1++;
		str2++;
	}
	return *str1 - *str2;
}

strncpy

把src所指的字符串以src地址开始的前n个字节复制到dest所指的数组中

char *strncpy(char *dest, const char *src, size_t n);
  • 如果源字符串的长度小于n, 则拷贝源字符串后, 在目标后面追加0, 直到n个
// 模拟实现
char *my_strncpy(char *dest, const char *src, size_t n) {
	unsigned int i = 0;
	char *ret = dest;
	while (*src != '\0' && i < n) {
		*dest++ = *src++;
		i++;
	}
	return ret;
}

strncat

把src所指的字符串的前n个字符添加到dest所指字符串的结尾处, 并覆盖dest所指字符串结尾的'\0'

char *strncat(char *dest, const char *src, size_t n);
// 模拟实现
char *my_strncat(char *dest, const char *src, size_t n) {
	char *ret = dest;
	if (dest != NULL && src != NULL) {
		while (*dest) {
			dest++;
		}
		while (n && (*dest++ = *src++) != '\0') {
			n--;
		}
		dest = '\0';
	}
	return ret;
}

strncmp

比较str1和str2的前n个字符是否相等

int strncmp(const char *str1, const char *str2, size_t n);
  • 相同, 返回0
  • str1大于str2, 返回大于0的值
  • str1小于str2, 返回小于0的值
int my_strncmp(const char *str1, const char *str2, size_t n) {
	assert(str1 != NULL);
	assert(str2 != NULL);
	while (n-- && *str1 && str2 && (*str1 == *str2)) {
		str1++;
		str2++;
	}
	return *str1 - *str2;
}

strstr

判断字符串str2是否是str1的子串

char *strstr(const char *str1, const char *str2);
  • 如果str2是str1的子串, 返回str1字符串从str2第一次出现的位置开始到str1结尾的字符串
  • 如果不是, 返回NULL
char *my_strstr(const char *str1, const char *str2) {
	assert(str1 != NULL);
	assert(str2 != NULL);
	if (*str2 == '\0') {
		return (char *)str1;
	}
	while (*str1 != '\0') {
		const char *p1 = str1;
		const char *p2 - str2;
		while (*p2 != '\0') {
			if (*p1 != *p2) {
				break;
			}
			else {
				p1++;
				p2++;
			}
 		}
 		if (*p2 == '\0') {
 			return (char *)str1;
 		}
 		++str1;
	}
	return NULL;
}

strtok

分解字符串, 以sep为分隔符分解str字符串

char *strtok(char *str, const char *sep);
  • sep参数是个字符串, 定义了用作分隔符的字符集合
  • 第一个参数指定一个字符串, 它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记
  • strtok函数找到str中的下一个标记, 并将其用'\0'结尾, 返回一个能指向该标记的指针
  • strtok函数的第一个参数不为NULL, 参数将找到str中第一个标记, strtok函数将保存它在字符串的位置

strerror

返回错误码所对应的的错误信息

char *strerror(int errnum);

memcpy

从src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中

void *memcpy(void *dest, const char *src, size_t n);
  • 这个函数在遇到'\0'的时候并不会停下来
  • 如果src与dest有任何的重叠, 复制的结果都是未定义的
// 模拟实现
void *my_memcpy(void *dest, const void *src, size_t n) {
	void *ret = dest;
	assert(dest);
	assert(src);
	while (n--) {
		*(char *)dest = *(char *)src;
		dest = (char *)dest + 1;
		src = (char *)src + 1;
	}
	return ret;
}

memmove

将src所指内存区域复制n个字节到dest所指内存区域

void *memmove(void *dest, const void *src, size_t n);
  • 和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的
// 模拟实现
void *my_memmove(void *dest, const void *src, size_t n) {
	char *ret = dest;
	const char *s = src;
	if (dest <= src || (char *)dest >= ((char *)src + n)) {
		while (n--) {
			*(ret++) = *(s++);
		}
	}
	else {
		while (n--) {
			*(ret + n) = *(s + n);
		}
	}
	return ret;
}

memcmp

比较内存区域ptr1和内存区域ptr2的前n个字节

int memcmp(const void *ptr1, const void *ptr2, size_t n);
  • 当ptr1 < ptr2时, 返回值小于0
  • 当ptr1 = ptr2时, 返回值等于0
  • 当ptr1 > ptr2时, 返回值大于0

我们的征途是星辰大海!