
#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变成无符号数后的一个巨大正数
3.模拟strlen函数的实现#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("%dn", ret); return 0; }
二、strcpy char* strcpy(char * destination, const char * source ); 注意点: 1.源字符串必须以 '' 结束 2.会将源字符串中的 '' 拷贝到目标空间(destination) 3.目标空间必须可变。
如上图,加了const后将会出错,*arr1无法修改
4.模拟strcpy函数的实现#include5 、strncpy函数 char * strncpy ( char * destination , const char * source , size_t num )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("%sn", arr1); return 0; }
#include#include int main() { char arr1[] = "***********"; char arr2[] = "hello world"; strncpy(arr1, arr2, 11); printf("%sn", arr1); return 0; }
使用:
1.拷贝num个字符从源字符串到目标空间。
2.如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加 '' ,直到num个。
三、strcat char * strcat ( char * destination, const char * source ); 注意点: 1.目标空间必须有足够的大,能容纳下源字符串的内容。 2.源字符串必须以 '' 结束。 3.目标空间必须可修改。 4.模拟strcat函数的实现
#include5. strncat函数#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("%sn", arr1); return 0; }
#include#include int main() { char arr1[20] = "abcdef"; char arr2[] = "ghijkl"; strncat(arr1, arr2, 6); printf("%sn", arr1); return 0; }
四、strcmp int strcmp ( const char * str1, const char * str2 ) 标准规定: 1.第一个字符串大于第二个字符串,则返回大于0的数字 2.第一个字符串等于第二个字符串,则返回0 3.第一个字符串小于第二个字符串,则返回小于0的数字 4.模拟strcmp函数的实现
#include5.strncmp函数int my_strcmp(char* arr1, char* arr2) { while (*arr1 == *arr2) { if (*arr1 == '') { 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("%dn", ret); return 0; }
#include#include int main() { char arr1[] = "abcdefg"; char arr2[] = "abcdegh"; printf("%dn",strncmp(arr1, arr2, 7)); return 0; }
使用:
比较到出现另个字符不一样或者一个字符串结束或者 num个字符全部比较完。五、strstr
char * strstr ( const char *str1, const char * str2)
注意:该函数返回一个指向在str1中第一次出现str2的起始地址(即在str1中寻找真子集str2),找不到则返回空指针NULL。
#include模拟实现strstr函数#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 == '') { return (char*)arr1; } while (*str1) { s1 = str1; s2 = arr2; while(*s1 == *s2) { s1++; s2++; if (*s2 == '') { 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; }
六、strtok char * strtok ( char * str, const char * sep ) 用法: 1.sep参数是个字符串,定义了用作分隔符的字符集合 2.第一个参数str指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记。 3.strtok函数找到str中的下一个标记,并将其用 结尾,返回一个指向这个标记的指针。(注: strtok函数会改变被 *** 作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容,并且可修改。) 4.strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。
运用:
#include#include int main() { const char* p = "@.#"; char arr1[] = "abc@def.ghi#jkl"; char arr2[20] = ""; strcpy(arr2, arr1);//将数据拷贝一份,处理arr2数组的内容 char* s = strtok(arr2, p); printf("%sn", s); s = strtok(NULL, p);//会记录上一次标记的位置,从那里开始 printf("%sn", s); s = strtok(NULL, p);//会记录上一次标记的位置,从那里开始 printf("%sn", 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; }
七、strerror
char * strerror ( int errnum )
1.错误码 --- 错误信息C语言中规定了一些信息,strerror可以把这些信息翻译出来
errno是C语言提供的一个全局变量,可以直接使用,放在errno.h文件中的
作用:当库函数使用的时候,发生错误会把errno这个全局的错误变量设置为本次执行库函数产生的错误码
使用:
#include3.strerror使用#include #include int main() { FILE* pf = fopen("test.txt", "r"); if (NULL == pf) { //打印出错误原因是什么 printf("%sn", strerror(errno)); return 0; } fclose(pf); pf = NULL; return 0; }
字符转换:
int tolower ( int c ); 将大写字符转换为小写字符 int toupper ( int c ); 将小写字符转换为大写字符#include#include int main() { char ch = 0; ch = getchar(); //大小写字母转换 if (islower(ch)) { ch = toupper(ch); } else { ch = tolower(ch); } printf("%cn", ch); return 0; }
八、memcpy void * memcpy ( void * destination, const void * source, size_t num ) 规定: 1.函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。 2.这个函数在遇到 '' 的时候并不会停下来。 3.如果source和destination有任何的重叠,复制的结果都是未定义的。
使用:
#include4.模拟memcpy函数的实现#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 void * memmove ( void * destination, const void * source, size_t num )
如果源空间和目标空间出现重叠,就得使用memmove函数处理。
区别:memmove函数处理的源内存块和目标内存块是可以重叠的。使用:
#include模拟memmove函数#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也能实现重叠拷贝
十、memcmp int memcmp ( const void * ptr1, const void * ptr2, size_t num ); 用法:比较从ptr1和ptr2指针开始的num个字节
使用:
#include#include int main() { char arr1[] = "abcdefghij"; char arr2[] = "abcdfghijk"; int n = memcmp(arr1, arr2, 5); printf("%dn", n); return 0; }
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)