C语言中对字符和字符串的处理很是频繁,但是C语言本身是没有字符串类型的,字符串通常放在常量字符串中或者字符串数组中。字符串常量适用于那些对他不做修改的字符串函数
长度不受限制的字符串函数:strcpy,strcat,strcmp
长度受限制的字符串函数:strncpy,strncat,strncmp
size_t strlen ( const char * str );
字符串已经'\0' 作为结束标志,strlen函数返回的是在字符串中'\0' 前面出现的字符个数(不包含'\0' )。
参数指向的字符串必须要以'\0' 结束。
注意函数的返回值为size_t,是无符号的( 易错)
学会strlen函数的模拟实现
- // int main()
- // {
- // if ((int)strlen("abc") - (int)strlen("abcdef") > 0)
- // {
- // printf("大于\n");
- // }
- // else
- // {
- // printf("小于等于\n");
- // }
-
-
- // return 0;
- // }
-
- //1
- size_t my_strlen(const char* str)
- {
- int count = 0;
- while (*str != '\0')
- {
- count++;
- str++;
- }
- return count;
- }
-
- //2.指针-指针
- //3.递归的方法
-
- int main()
- {
- size_t sz = my_strlen("abc");
- printf("%d\n",sz);
- return 0;
- }
char* strcpy(char * destination, const char * source );
Copies the C string pointed by source into the array pointed by destination, including the terminating null character (and stopping at that point).
源字符串必须以 '\0'结束。
会将源字符串中的 '\0'拷贝到目标空间。
目标空间必须足够大,以确保能存放源字符串。
目标空间必须可变。
学会模拟实现。
- char* my_strcpy(char* dest,const char* src)
- {
- char* ret = dest;
- assert(dest != NULL); //断言,dest不为空指针
- assert(src != NULL);
- // while(*src != '\0')
- // {
- // *dest = *src;
- // dest++;
- // src++;
- // }
- // *dest = *src; // \0
- while(*dest++ = *src++)
- {
- ;
- }
-
-
- return ret;
- }
-
- int main()
- {
- char arr1[20] = "hello xiaofan";
- //char arr2[40] = "hello xiaofan";
- char arr2[] = "xxxxx";
- //strcpy(arr1,arr2);
- my_strcpy(arr1,arr2);
- printf("%s\n",arr1);
-
- return 0;
- }
char * strcat ( char * destination, const char * source );
Appends a copy of the source string to the destination string. The terminating null character in destination is overwritten by the first character of source, and a null-character is included at the end of the new string formed by the concatenation of both in destination.
源字符串必须以 '\0'结束。
目标空间必须有足够的大,能容纳下源字符串的内容。
目标空间必须可修改。
- char* my_strcat(char* dest,const char* src)
- {
- assert(dest != NULL);
- assert(src != NULL);
- char* ret = dest;
- //1.找到目标空间中的\0
- while (*dest != '\0')
- {
- dest++;
- }
- while (*dest++ = *src++)
- {
- ;
- }
-
- return ret;
-
-
- }
-
- int main()
- {
- char arr1[20] = "hello ";
- char arr2[] = "world";
-
- //strcat(arr1,arr2);
- my_strcat(arr1,arr2);
-
- printf("%s\n",arr1); //helloworld
-
- return 0;
- }
int strcmp ( const char * str1, const char * str2 );
标准规定:
第一个字符串大于第二个字符串,则返回大于0的数字
第一个字符串等于第二个字符串,则返回0
第一个字符串小于第二个字符串,则返回小于0的数字那么如何判断两个字符串?
- int my_strcmp(const char* str1,const char* str2)
- {
- assert(str1 && str2 != NULL);
- while (*str1 == *str2)
- {
- if (*str1 == '\0')
- {
- return 0;
- }
- str1++;
- str2++;
- }
- // if(*str1 > *str2)
- // {
- // return 1;
- // }
- // else
- // {
- // return -1;
- // }
- return (*str1 - *str2);
-
- }
-
- int main()
- {
- //char arr1[] = "abcdef\0";
- //char arr2[] = "abcddddd\0";
- int ret = my_strcmp("abcdefa","abcdefb"); //-1
- printf("%d\n",ret);
- return 0;
- }
char * strncpy ( char * destination, const char * source, size_t num );
拷贝num个字符从源字符串到目标空间。
如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个。
- int main()
- {
- char arr1[20] = "abcdef";
- char arr2[] = "ab";
- strncpy(arr1,arr2,4);
- printf("%s\n",arr1);
-
- return 0;
- }
char * strncat ( char * destination, const char * source, size_t num );
- int main()
- {
- char arr1[20] = "abcdef";
- char arr2[] = "ab";
- strncat(arr1,arr2,0);
- printf("%s\n",arr1);
-
- return 0;
- }
int strncmp ( const char * str1, const char * str2, size_t num )
- int main()
- {
- char arr1[] = "abcqbertyui";
- char arr2[] = "abcqcfg";
- printf("%d\n",strncmp(arr1,arr2,5));
-
- return 0;
- }
char * strstr ( const char *, const char * );
- char* my_strstr(const char* str1,char* str2)
- {
- assert(str1 && str2 != NULL);
- char* cp = str1;
- char* s1 = cp;
- char* s2 = str2;
- while (*cp)
- {
- //开始匹配
- s1 = cp;
- s2 = str2;
- while (*s1 != '\0' && *s2 != '\0' && *s1 == *s2)
- {
- s1++;
- s2++;
- }
- if (*s2 == '\0')
- {
- return cp;
- }
-
-
- cp++;
- }
-
- return NULL;
-
- }
-
- int main()
- {
- char arr1[] = "abcdefabcdef";
- //char arr2[] = "deq"; //null
- char arr2[] = "def";
- //char* ret = strstr(arr1,arr2);
- char* ret = my_strstr(arr1,arr2);
- if (ret != NULL)
- {
- printf("%s\n",ret);
- }
- else
- {
- printf("找不到\n");
- }
-
-
- return 0;
- }
char * strtok ( char * str, const char * sep );
sep参数是个字符串,定义了用作分隔符的字符集合
第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记。
strtok函数找到str中的下一个标记,并将其用 \0结尾,返回一个指向这个标记的指针(注:strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。)
strtok函数的第一个参数不为 NULL,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。 strtok函数的第一个参数为 NULL,函数将在同一个字符串中被保存的位置开始,查找下一个标记。
如果字符串中不存在更多的标记,则返回 NULL指针。
- int main()
- {
- char arr[] = "fsy@qq.com@77#2222";
- char copy[20];
- strcpy(copy,arr);
-
- char sep[] = "@.#";
- // char* ret = strtok(copy,sep);
- // printf("%s\n",ret);
- // ret = strtok(NULL,sep);
- // printf("%s\n",ret);
- // ret = strtok(NULL,sep);
- // printf("%s\n",ret);
-
- char* ret = NULL;
-
- for(ret = strtok(copy,sep); ret != NULL; ret = strtok(NULL,sep))
- {
- printf("%s\n",ret);
- }
-
- return 0;
- }
char * strerror ( int errnum );
返回错误码,所对应的错误信息
库函数在执行的时候吗,发生了错误,会将一个错误码放在errno这个变量中
errno是C语言提供的一个全局的变量
- int main()
- {
- int i = 0;
- for (i= 0; i < 10; i++)
- {
- printf("%s\n",strerror(i));
- }
-
- return 0;
- }
-
- int main()
- {
- //C语言中可以操作文件
- //操作文件的步骤
- //1.打开文件
- //2.读/写文件
- //3.关闭文件
- //FILE* pf = fopen("/Users/fan/Documents/c_study/c_test20/data.txt","r");
- FILE* pf = fopen("fan/Documents/c_study","r");
- if (pf == NULL)
- {
- printf("%s\n",strerror(errno));
- perror("fopen");
- return 1;
- }
-
- //读文件
-
- //关闭文件
- fclose(pf);
-
- return 0;
- }
- int main()
- {
- //判断为真是非0,为假是0
- //printf("%d\n",isupper('A'));
- //printf("%d\n",isdigit('1'));
-
- //字符转换
- // printf("%c\n",tolower('A'));
- // printf("%c\n",tolower('s'));
-
- char arr[20] = {0};
- gets(arr); //遇到空格也会往后读
- printf("%s\n",arr);
-
- char* p = arr;
- while(*p)
- {
- if(isupper(*p)) //*p >= 'A' && *p<='Z'
- {
- *p = tolower(*p); //*p = *p+32
- }
- p++;
- }
- printf("%s\n",arr);
- return 0;
- }
void * memcpy ( void * destination, const void * source, size_t num );
函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。这个函数在遇到 '\0'的时候并不会停下来。
如果source和destination有任何的重叠,复制的结果都是未定义的。
- //memcpy(void* dest,)
- //memcpy 是内存拷贝 拷贝字符串,拷贝整型数组,拷贝结构体数据
- // int main()
- // {
- // // int arr1[] = {1,2,3,4,5,6,7,8,9,10};
- // // int arr2[20] = {0};
- // float arr1[] = {1.0,2.0,3.0};
- // float arr2[5] = {0};
- // //将arr1的内容,拷贝到arr2中
- // memcpy(arr2,arr1,8);
- // int i = 0;
- // for (i = 0 ;i < 5; i++)
- // {
- // printf("%f ",arr2[i]);
- // }
-
- // return 0;
- // }
-
- //模拟实现
-
- //函数拷贝结束后,返回目标空间的起始地址
- void* my_memcpy(void* dest,const void* src,size_t num)
- {
- assert(dest && src != NULL);
- void* ret = dest;
- while (num--) //4,3,2,1,0
- {
- *(char*)dest = *(char*)src;
- dest = (char*)dest+1; //强制转换成char* ,跳过一个字节
- src = (char*)src+1;
- }
- return ret;
-
- }
-
- int main()
- {
- int arr1[] = {1,2,3,4,5,6,7,8,9,10};
- //01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 05 00 00 00 00
- int arr2[20] = {0};
- //my_memcpy(arr2,arr1,21);
- //my_memcpy(arr1+2,arr1,21); //memcpy函数是用来处理,不重叠的内存拷贝的
- memmove(arr1+2,arr1,20); //memmove函数可以用来处理重叠的内存拷贝
- int i = 0;
- for (i = 0 ;i < 10; i++)
- {
- printf("%d ",arr1[i]);
- }
-
-
- return 0;
- }
void * memmove ( void * destination, const void * source, size_t num );
和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。如果源空间和目标空间出现重叠,就得使用memmove函数处理。
- void* my_memmove(void* dest,void* src,size_t num)
- {
- void* ret = dest;
- assert(dest && src != NULL);
- if (dest < src)
- {
- //前->后
- while (num--)
- {
- *(char*)dest = *(char*)src;
- dest = (char*)dest +1;
- src = (char*)src +1;
- }
- }
- else
- {
- //后->前
- while (num--) //20
- {
- *((char*)dest + num) = *((char*)src + num);
- }
- }
- return ret;
- }
-
- int main()
- {
- int arr1[] = {1,2,3,4,5,6,7,8,9,10};
- //01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 05 00 00 00 00
- //int arr2[20] = {0};
- //my_memcpy(arr2,arr1,21);
- //my_memcpy(arr1+2,arr1,21); //memcpy函数是用来处理,不重叠的内存拷贝的
- //memmove(arr1+2,arr1,20); //memmove函数可以用来处理重叠的内存拷贝
- my_memmove(arr1+2,arr1,20);
- //memcpy(arr1+2,arr1,20);err
- int i = 0;
- for (i = 0 ;i < 10; i++)
- {
- printf("%d ",arr1[i]);
- }
-
-
- return 0;
- }
int memcmp ( const void * ptr1,const void * ptr2,size_t num );
比较从ptr1和ptr2指针开始的num个字节
- // int main()
- // {
- // char arr[] = "hello bit";
- // memset(arr+1,'x',4);//以字节为单位设置的
- // printf("%s\n",arr); // hxxxx bit
-
- // return 0;
- // }
-
- int main()
- {
- int arr[10] = {0};
- //memset(arr,1,10); err
- memset(arr,1,40);
-
- return 0;
- }