#include
#include
int main()
{
char arr1[] = "abc";
char arr2[] = "abcdef";
if (strlen(arr1) - strlen(arr2) > 0)// 3 - 6
{
printf(">\n");
}
else
{
printf("<=\n");
}
return 0;
}
如这串代码,输出结果为:
为什么打印结果不是: <=
原因:strlen函数返回值是无符号数,3-6不会为负数,而是-3变成无符号数后的一个巨大正数
#include
#include
int my_strlen(const char* arr)
{
assert(arr);
int count = 0;
while (*arr)
{
arr++;
count++;
}
return count;
}
int main()
{
char arr[] = "abcdef";
int ret = my_strlen(arr);
printf("%d\n", ret);
return 0;
}
如上图,加了const后将会出错,*arr1无法修改
#include
char* my_strcpy(char*arr1,const char*arr2)
{
char* ret = arr1;
while (*arr1++ = *arr2++)
{
;
}
return ret;
}
int main()
{
char arr1[20] = "";
char arr2[] = "abcdef";
my_strcpy(arr1, arr2);
printf("%s\n", arr1);
return 0;
}
#include
#include
int main()
{
char arr1[] = "***********";
char arr2[] = "hello world";
strncpy(arr1, arr2, 11);
printf("%s\n", arr1);
return 0;
}
使用:
1.拷贝num个字符从源字符串到目标空间。
2.如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加 '\0' ,直到num个。
#include
#include
char* my_strcat(char* arr1, const char* arr2)
{
char* ret = arr1;
assert(arr1 && arr2);
while (*arr1)
{
arr1++;
}
while (*arr1++ = *arr2++)
{
;
}
return ret;
}
int main()
{
char arr1[20] = "abcdef";
char arr2[] = "ghijkl";
my_strcat(arr1, arr2);
printf("%s\n", arr1);
return 0;
}
#include
#include
int main()
{
char arr1[20] = "abcdef";
char arr2[] = "ghijkl";
strncat(arr1, arr2, 6);
printf("%s\n", arr1);
return 0;
}
#include
int my_strcmp(char* arr1, char* arr2)
{
while (*arr1 == *arr2)
{
if (*arr1 == '\0')
{
return 0;
}
arr1++;
arr2++;
}
if (*arr1 > *arr2)
{
return 1;
}
else
{
return -1;
}
}
int main()
{
char arr1[] = "abcdef";
char arr2[] = "abcefg";
int ret = my_strcmp(arr1, arr2);
printf("%d\n", ret);
return 0;
}
#include
#include
int main()
{
char arr1[] = "abcdefg";
char arr2[] = "abcdegh";
printf("%d\n",strncmp(arr1, arr2, 7));
return 0;
}
使用:
char * strstr ( const char *str1, const char * str2)
该函数返回一个指向在str1中第一次出现str2的起始地址(即在str1中寻找真子集str2),找不到则返回空指针NULL。
#include
#include
int main()
{
char arr1[] = "abcdefghi";
char arr2[] = "efg";
char* str = strstr(arr1, arr2);
if (str == NULL)
{
printf("找不到\n");
}
else
{
printf("找到了\n");
}
return 0;
}
#include
#include
char* my_strstr(const char* arr1, const char* arr2)
{
const char* str1 = arr1;
const char* s1 = str1;
const char* s2 = arr2;
assert(arr1 && arr2);
if (*arr2 == '\0')
{
return (char*)arr1;
}
while (*str1)
{
s1 = str1;
s2 = arr2;
while(*s1 == *s2)
{
s1++;
s2++;
if (*s2 == '\0')
{
return (char*)str1;
}
}
str1++;
}
return NULL;
}
int main()
{
char arr1[] = "abbbcdefg";
char arr2[] = "bbc";
char* ret = my_strstr(arr1, arr2);
if (NULL == ret)
{
printf("找不到\n");
}
else
{
printf("找到了\n");
}
return 0;
}
运用:
#include
#include
int main()
{
const char* p = "@.#";
char arr1[] = "[email protected]#jkl";
char arr2[20] = "";
strcpy(arr2, arr1);//将数据拷贝一份,处理arr2数组的内容
char* s = strtok(arr2, p);
printf("%s\n", s);
s = strtok(NULL, p);//会记录上一次标记的位置,从那里开始
printf("%s\n", s);
s = strtok(NULL, p);//会记录上一次标记的位置,从那里开始
printf("%s\n", s);
return 0;
}
效果:
更简化高效版:
#include
#include
int main()
{
char arr1[] = "abc*def.ghi#jkl";
char arr2[20] = "";
strcpy(arr2,arr1);
const char* p = "*.#";
char* str = NULL;
int i = 0;
for (str = strtok(arr2, p); str != NULL; str = strtok(NULL, p))
{
printf("%s ", str);
}
return 0;
}
char * strerror ( int errnum )
C语言中规定了一些信息,strerror可以把这些信息翻译出来
0 | No error |
1 | Operation not permitted |
2 | No such file or directory |
3 | No such process |
4 | Interrupted function call |
5 | Input/output error |
6 | No such device or address |
7 | Arg list too long |
8 | Exec format error |
9 | Bad file descriptor |
errno是C语言提供的一个全局变量,可以直接使用,放在errno.h文件中的
作用:当库函数使用的时候,发生错误会把errno这个全局的错误变量设置为本次执行库函数产生的错误码
使用:
#include
#include
#include
int main()
{
FILE* pf = fopen("test.txt", "r");
if (NULL == pf)
{
//打印出错误原因是什么
printf("%s\n", strerror(errno));
return 0;
}
fclose(pf);
pf = NULL;
return 0;
}
函数 |
如果他的参数符合下列条件就返回真
|
iscntr
|
任何控制字符
|
isspace
|
空白字符:空格 ‘ ’ ,换页 ‘\f’ ,换行 '\n' ,回车 ‘\r’ ,制表符 '\t' 或者垂直制表符 '\v'
|
isdigit
|
十进制数字 0~9
|
isxdigit
|
十六进制数字,包括所有十进制数字,小写字母 a~f ,大写字母 A~F
|
islower
|
小写字母 a~z
|
isupper
|
大写字母 A~Z
|
isalpha
|
字母 a~z 或 A~Z
|
isalnum
|
字母或者数字, a~z,A~Z,0~9
|
ispunct
|
标点符号,任何不属于数字或者字母的图形字符(可打印)
|
isgraph
|
任何图形字符
|
isprint
|
任何可打印字符,包括图形字符和空白字符
|
字符转换:
#include
#include
int main()
{
char ch = 0;
ch = getchar();
//大小写字母转换
if (islower(ch))
{
ch = toupper(ch);
}
else
{
ch = tolower(ch);
}
printf("%c\n", ch);
return 0;
}
使用:
#include
#include
int main()
{
int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
int arr2[5] = { 0 };
memcpy(arr2, arr1 + 5, 5 * sizeof(arr1[0]));
for (int i = 0; i < 5; i++)
{
printf("%d ", arr2[i]);
}
return 0;
}
#include
#include
void* my_memcpy(void* arr2, const void* arr1, size_t num)
{
void* ret = arr2;
assert(arr1 && arr2);
while (num--)
{
*(char*)arr2 = *(char*)arr1;
arr1 = (char*)arr1 + 1;
arr2 = (char*)arr2 + 1;
}
return ret;
}
int main()
{
int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
int arr2[5] = { 0 };
my_memcpy(arr2, arr1 + 5, 5 * sizeof(arr1[0]));
for (int i = 0; i < 5; i++)
{
printf("%d ", arr2[i]);
}
return 0;
}
如果源空间和目标空间出现重叠,就得使用memmove函数处理。
使用:
#include
#include
int main()
{
int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
memmove(arr1+3, arr1 , 3 * sizeof(arr1[0]));
for (int i = 0; i < 10; i++)
{
printf("%d ", arr1[i]);
}
return 0;
}
#include
#include
void* my_memmove(void* arr1, const void* arr2, size_t num)
{
void* ret = arr1;
assert(arr1 && arr2);
if (arr1 < arr2)
{
while (num--)
{
*(char*)arr1 = *(char*)arr2;
arr1 = (char*)arr1 + 1;
arr2 = (char*)arr2 + 1;
}
}
else
{
while (num--)
{
*((char*)arr1 + num) = *((char*)arr2 + num);
}
}
return ret;
}
int main()
{
int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
my_memmove(arr1+3, arr1, 3 * sizeof(arr1[0]));
for (int i = 0; i < 10; i++)
{
printf("%d ", arr1[i]);
}
return 0;
}
一般来说,memcpy用来拷贝不重叠的空间,memmove去处理那些重叠内存拷贝
特别的是,在VS里memcpy也能实现重叠拷贝
Return Value | Relationship of First count Bytes of buf1 and buf2 |
<0 | buf1 less than buf2 |
0 | buf1 identical to buf2 |
>0 | buf1 greater than buf2 |
使用:
#include
#include
int main()
{
char arr1[] = "abcdefghij";
char arr2[] = "abcdfghijk";
int n = memcmp(arr1, arr2, 5);
printf("%d\n", n);
return 0;
}