strlen
// 计数器实现
int my_strlen_count(const char* parr) {
int count = 0;
assert(parr);
while (*parr != '\0') { // 不严谨,对指针解引用必须是非空指针
parr++;
count++;
}
return count;
}
// 不允许创建临时变量,用递归
int my_strlen_recursive(const char* parr) {
if (*parr == '\0')
return 0;
return 1 + my_strlen_recursive(parr + 1);
}
// 指针-指针版本
int my_strlen_ptr(const char* parr) {
assert(parr);
const char* tmp = parr;
while (*parr) { // a
parr++;
}
return parr - tmp;
}
int main() {
//strlen
char arr[] = "abc";
int len = my_strlen_ptr(arr);
int sz = sizeof(arr);
printf("%d\n", sz);
printf("%d\n", len);
return 0;
}
// 试题
int main() {
if (strlen("abc") - strlen("abcdefg") > 0) {
printf(">\n");
} else {
printf("<=\n");
}
return 0;
}
// 输出结果是>
// size_t strlen(const char* str);
// 返回值是size_t
// C语言中typedef unsigned __int64 size_t;
// 是无符号整形
可见,strlen("abc") - strlen("abcdefg")确实是小于0的数,但是返回值是无符号整形,所以要进行转换
最后的结果是一个很大的整数
strcpy
函数原型
char* strcpy(char* dest, const char* src);
// 模拟实现
char* my_strcpy(char* dest, const char* src) {
assert(src && dest);
char* tmp = dest;
while (*dest++ = *src++);
return tmp;
}
int main() {
char arr[20] = { 0 };
char* parr = "hello!";
my_strcpy(arr, parr);
printf("%s\n", arr);
return 0;
}
strcat
char *strcat( char *strDestination, const char *strSource );
// 源字符串必须以'\0' 结束。
// 目标空间必须有足够的大,能容纳下源字符串的内容。
// 目标空间必须可修改。
// 模拟实现
// strcat
char* my_strcat(char* dest, const char* src) {
assert(dest && src);
char* tmp = dest;
while (*dest) {
dest++;
}
while (*dest++ = *src++);
return tmp;
}
int main() {
char arr[20] = { 'h', 'e', 'l', '\0', 'm'};
char arr2[10] = " world";
printf("%s\n", my_strcat(arr, arr2));
return 0;
}
strcmp
int strcmp( const char *string1, const char *string2 );
// 模拟实现
// 版本1
int my_strcmp01(const char* string1, const char* string2) {
assert(string1 && string2);
while (*string1 || *string2) {
if (*string1 != *string2)
return *string1 - *string2;
if (*string1 == *string2) {
string1++;
string2++;
}
}
return 0;
}
// 版本2
int my_strcmp(const char* string1, const char* string2) {
assert(string1 && string2);
while (*string1 == *string2 && *string) {
string1++;
string2++;
}
return *string1 - *string2;
}
int main() {
char arr[] = "hello";
char arr2[] = "hp";
if (my_strcmp(arr,arr2)> 0) {
printf(">\n");
} else if (my_strcmp(arr, arr2) == 0) {
printf("=\n");
} else {
printf("<\n");
}
return 0;
}
strncmp
int strncmp(const char* str1, const char* str2, size_t count);
// 模拟实现
int my_strncmp(const char* str1, const char* str2, size_t count) {
assert(str1 && str2);
char* tmp_str1 = str1;
for (int i = 0; i < count; i++) {
tmp_str1++;
}
//char* tmp_str2 = str2;
while (*str1 == *str2 && *str1) {
if (str1 < tmp_str1) {
str1++;
str2++;
}
}
return *str1 - *str2;
}
strncat
char* strncat(char* dest, char* src, size_t count);
// 模拟实现
char* my_strncat(char* dest, const char* src, int count) {
int i = 0;
char* tmp_dest = dest;
char* tmp_src = src;
while (*dest)
dest++;
while ( i < count) {
src++;
i++;
}
while (tmp_src < src) {
*dest++ = *tmp_src++;
}
return tmp_dest;
}
int main() {
char string1[20] = "hello";
char* string2 = " world!";
printf("%s\n", my_strncat(string1, string2, 5));
return 0;
}
strstr
char *strstr( const char *string, const char *strCharSet );
// 模拟实现
char* my_strstr(const char* str1, const char* str2) {
assert(str1 && str2);
const char* s1 = NULL;
const char* s2 = NULL;
const char* cp = str1;
if (*str2 == '\0')
return (char*)str1;
while (*cp) {
s1 = cp;
s2 = str2;
while (*s1 && *s2 && (*s1 == *s2)) {
s1++;
s2++;
}
if ('\0' == *s2)
return (char*)cp;
if ('\0' == *s1)
return NULL;
cp++;
}
return NULL;
}
strtok
char *strtok( char *strToken, const char *strDelimit );
// strDelimit分隔符字符集
strerror
include <errno.h>
// errno是一个全局的错误码,用的时候要包含头文件
strerro(errno);
错误信息
-
联系
-
strerror
-
是将错误码转换成错误信息,返回值是错误信息对应字符串的首地址
-
引用头文件<string.h>
-
// 函数原型 char* strerror(int errnum);
-
-
perror
-
直接打印错误信息
-
引用头文件<stdio.h>或者<stdlib.h>
-
// 函数原型 void perror(const char* string)
-
-
-
perror(""),括号里面是自定义的,可以自己写,把自己写的内容打印出来后会加上一个冒号以及错误信息;
这里的错误信息是将错误码转换成错误信息才打印出来的
字符分类函数
需要引用<ctype.h>
字符转换函数
需要引用<ctype.h>
toupper();
tolower();