网站的动画效果代码大全,网站开发 私活,微信网站建设需要那些资料,网络营销有哪些具体方法本章重点 重点介绍处理字符和字符串的库函数的使用和注意事项 目录 0.前言 1.函数介绍 1.1 strlen - 计算字符串长度 1.2 strcpy - 复制字符串 1.3 strcat - 追加字符串 1.4 strcmp - 字符串比较 1.5 strncpy - 受限制复制 1.6 strncat - 受限制追加 1.7 strncmp - 受限制比… 本章重点 重点介绍处理字符和字符串的库函数的使用和注意事项 目录 0.前言 1.函数介绍 1.1 strlen - 计算字符串长度 1.2 strcpy - 复制字符串 1.3 strcat - 追加字符串 1.4 strcmp - 字符串比较 1.5 strncpy - 受限制复制 1.6 strncat - 受限制追加 1.7 strncmp - 受限制比较 1.8 strstr 1.9 strtok 1.10 strerror - 返回错误信息 1.11 memcpy - 内存复制 1.12 memmove 1.13 memcmp - 比较两个内存块 2. 库函数的模拟实现 2.1 模拟实现strlen 2.2 模拟实现strcpy 2.3 模拟实现strcat 2.4 模拟实现strstr 2.5 模拟实现strcmp 2.6 模拟实现memcpy 2.7 模拟实现memmove 求字符串长度 strlen 长度不受限制的字符串函数 strcpy strcat strcmp 长度受限制的字符串函数介绍 strncpy strncat strncmp 字符串查找 strstr strtok 错误信息报告 strerror 字符操作 内存操作函数 memcpy memmove memset memcmp 0.前言 C语言中对字符和字符串的处理很是频繁但是C语言本身是没有字符串类型的字符串通常放在常量字符串中或者字符数组中。 字符串常量适用于那些对它不做修改的字符串函数. 1.函数介绍
1.1 strlen - 计算字符串长度 #includesdio.h //头文件 size_t strlen ( const char * str ); 解析计算 sizeof - 操作符 - 计算大小 size_t - unsigned int; 字符串已经 \0 作为结束标志strlen函数返回的是在字符串中 \0 前面出现的字符个数不包含 \0 )。参数指向的字符串必须要以 \0 结束。 注意函数的返回值为size_t是无符号的 易错 学会strlen函数的模拟实现 C语言中 strlen 和 sizeof 的区别 1. strlen 是一个库函数使用时需要引用 #includesdio.h 这个头文件而sizeof是一个运算符号 2.strlen 计算的是\0之前的字符个数sizeof计算的是所占空间内存的大小单位是字节 3.strlen计算式不包含\0,而sizeof 包含\0; 4.strlen 遇到 \0 才结束 5.sizeof的类型是unsigned int, 是一个无符号的整型 6.strlen 只能用char 做参数sizeof可以用类型做参数 总结以上是sizeof和strlen的区别需要特别注意的是strlen只有在遇到\0时才会结束就是只计算\0之前的字符所以我们在使用时一定要记得加上\0 在使用sizeof 时必须要记住数组名是首元素地址有两个除外 1. sizeof(数组名)计算的是整个数组的大小单位是字节 2. 数组名表示的是整个数组的地址 #includestdio.h
#includestring.h
#includeassert.hint my_strlen(const char* str)
{assert(str);int count 0;while (*str ! \0){count;str;}return count;
}
int main()
{int len strlen(abcdef);int len1 my_strlen(abcdefaaa);printf(%d\n, len);printf(%d\n, len1);return 0;
} 注 #include stdio.h
int main()
{const char*str1 abcdef;const char*str2 bbb;if(strlen(str2)-strlen(str1)0){printf(str2str1\n);} else{printf(srt1str2\n);}return 0;
} 1.指针不知道赋什么值就给NULL 2.指针使用完后赋值NULL 1.2 strcpy - 复制字符串 #includestring.h 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 拷贝到目标空间。 目标空间必须足够大以确保能存放源字符串。 目标空间必须可变。 学会模拟实现。 1.3 strcat - 追加字符串 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 结束。 目标空间必须有足够的大能容纳下源字符串的内容。 目标空间必须可修改。 字符串自己给自己追加如何 1.4 strcmp - 字符串比较 int strcmp ( const char * str1 , const char * str2 ); This function starts comparing the first character of each string. If they are equal to each other, it continues with the following pairs until the characters differ or until a terminating null-character is reached. 标准规定 第一个字符串大于第二个字符串则返回大于0的数字 //0第一个字符串等于第二个字符串则返回0 //0第一个字符串小于第二个字符串则返回小于0的数字 //0那么如何判断两个字符串 1.5 strncpy - 受限制复制字符串 char * strncpy ( char * destination , const char * source , size_t num ); Copies the first num characters of source to destination. If the end of the source C string (which is signaled by a null-character) is found before num characters have been copied, destination is padded with zeros until a total of num characters have been written to it. 拷贝num个字符从源字符串到目标空间。 如果源字符串的长度小于num则拷贝完源字符串之后在目标的后边追加0直到num个。 1.6 strncat - 受限制追加字符串 char * strncat ( char * destination , const char * source , size_t num ); Appends the first num characters of source to destination, plus a terminating null-character. If the length of the C string in source is less than num, only the content up to the terminating null-character is copied.译将源字符串的num个字符追加到目标字符串后加上一个NULL译如果源字符串的长度小于num则只包含到终止null字符被追加 /* strncat example */
#include stdio.h
#include string.h
int main ()
{char str1[20];char str2[20];strcpy (str1,To be );strcpy (str2,or not to be);strncat (str1, str2, 6);puts (str1);return 0;
} 结果 1.7 strncmp - 受限制比较字符串 int strncmp ( const char * str1 , const char * str2 , size_t num ); 比较到出现另个字符不一样或者一个字符串结束或者num个字符全部比较完。 /* strncmp example */
#include stdio.h
#include string.h
int main ()
{char str[][5] { R2D2 , C3PO , R2A6 };int n;puts (Looking for R2 astromech droids...);for (n0 ; n3 ; n)if (strncmp (str[n],R2xx,2) 0){printf (found %s\n,str[n]);}return 0;
} 1.8 strstr char * strstr ( const char * str1 , const char * str2 ); Returns a pointer to the first occurrence of str2 in str1, or a null pointer if str2 is not part of str1. /* strstr example */
#include stdio.h
#include string.h
int main ()
{char str[] This is a simple string;char * pch;pch strstr (str,simple);strncpy (pch,sample,6);puts (str);return 0;
} 1.9 strtok char * strtok ( char * str , const char * sep ); sep参数是个字符串定义了用作分隔符的字符集合 第一个参数指定一个字符串它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记。 strtok 函数找到 str 中的下一个标记并将其用 \0 结尾返回一个指向这个标记的指针。注 strtok 函数会改变被操作的字符串所以在使用 strtok 函数切分的字符串一般都是临时拷贝的内容 并且可修改。 strtok函数的第一个参数不为 NULL 函数将找到 str 中第一个标记 strtok 函数将保存它在字符串中的位置。 strtok函数的第一个参数为 NULL 函数将在同一个字符串中被保存的位置开始查找下一个标记。 如果字符串中不存在更多的标记则返回 NULL 指针。 /* strtok example */
#include stdio.h
#include string.h
int main ()
{char str[] - This, a sample string.;char * pch;printf (Splitting string \%s\ into tokens:\n,str);pch strtok (str, ,.-);while (pch ! NULL){printf (%s\n,pch);pch strtok (NULL, ,.-);}return 0;
} #include stdio.h
int main()
{char *p zhangpengweibitedu.tech;const char* sep .;char arr[30];char *str NULL;strcpy(arr, p);//将数据拷贝一份处理arr数组的内容for(strstrtok(arr, sep); str ! NULL; strstrtok(NULL, sep)){printf(%s\n, str);}
} 1.10 strerror - 返回错误信息 char * strerror ( int errnum ); 返回错误码所对应的错误信息。 /* strerror example : error list */
#include stdio.h
#include string.h
#include errno.h//必须包含的头文件
int main ()
{ FILE * pFile;pFile fopen (unexist.ent,r);if (pFile NULL)printf (Error opening file unexist.ent: %s\n,strerror(errno));//errno: Last error numberreturn 0;
}
Edit Run 字符分类函数 函数 如果他的参数符合下列条件就返回真 iscntrl 任何控制字符 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 任何可打印字符包括图形字符和空白字符 字符转换 int tolower ( int c ); int toupper ( int c); /* isupper example */
#include stdio.h
#include ctype.h
int main ()
{int i0;char str[]Test String.\n;char c;while (str[i]){cstr[i];if (isupper(c)) ctolower(c);putchar (c);i;}return 0;
} 1.11 memcpy - 内存复制 void * memcpy ( void * destination , const void * source , size_t num ); 函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。 这个函数在遇到 \0 的时候并不会停下来。 如果source和destination有任何的重叠复制的结果都是未定义的。 /* memcpy example */
#include stdio.h
#include string.h
struct {char name[40];int age;
} person, person_copy;
int main ()
{char myname[] Pierre de Fermat;/* using memcpy to copy string: */memcpy ( person.name, myname, strlen(myname)1 );person.age 46;/* using memcpy to copy structure: */memcpy ( person_copy, person, sizeof(person) );printf (person_copy: %s, %d \n, person_copy.name, person_copy.age );return 0;
} 结果 1.12 memmove-内存移动 void * memmove ( void * destination , const void * source , size_t num ); 和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。 如果源空间和目标空间出现重叠就得使用memmove函数处理。 /* memmove example */
#include stdio.h
#include string.h
int main ()
{char str[] memmove can be very useful......;memmove (str20,str15,11);puts (str);return 0;
} 结果 1.13 memcmp - 比较两个内存块 int memcmp ( const void * ptr1 , const void * ptr2 , size_t num ); 比较两个内存块 比较第一个数字指向的内存块的字节数ptr1到第一个数字指向的字节数ptr2如果它们都匹配则返回零如果不匹配则返回一个不同于零的值表示哪个值更大。 注意不像strcmp函数在找到空字符后不会停止比较。 比较从ptr1和ptr2指针开始的num个字节 返回值如下 /* memcmp example */
#include stdio.h
#include string.hint main ()
{char buffer1[] DWgaOtP12df0;char buffer2[] DWGAOTP12DF0;int n;nmemcmp ( buffer1, buffer2, sizeof(buffer1) );if (n0) printf (%s is greater than %s.\n,buffer1,buffer2);else if (n0) printf (%s is less than %s.\n,buffer1,buffer2);else printf (%s is the same as %s.\n,buffer1,buffer2);return 0;
} 输出: DWgaOtP12df0 is greater than DWGAOTP12DF0.DWgAOtp12Df0大于DWGAOTP12DF0因为两个单词中第一个不匹配的字符是 g 和 G 分别为和 g (103)评估为大于 G (71). 2. 库函数的模拟实现 2.1 模拟实现strlen 三种方式 方式 1 //计数器方式
int my_strlen(const char * str)
{int count 0;while(*str){count;str;}return count;
} 方式 2 //不能创建临时变量计数器
int my_strlen(const char * str)
{if(*str \0)return 0;elsereturn 1my_strlen(str1);
} 方式 3 //指针-指针的方式
int my_strlen(char *s)
{char *p s;while(*p ! ‘\0’ )p;return p-s;
} 2.2 模拟实现strcpy 参考代码 //1.参数顺序
//2.函数的功能停止条件
//3.assert
//4.const修饰指针
//5.函数返回值
//6.题目出自《高质量C/C编程》书籍最后的试题部分
char *my_strcpy(char *dest, const char*src)
{ char *ret dest;assert(dest ! NULL);assert(src ! NULL);while((*dest *src)){;}return ret;
} 2.3 模拟实现strcat char *my_strcat(char *dest, const char*src)
{char *ret dest;assert(dest ! NULL);assert(src ! NULL);while(*dest){dest;}while((*dest *src)){;}return ret;
} 2.4 模拟实现strstr 注可以自己研究一下 KMP 算法 char* strstr(const char* str1, const char* str2)
{char* cp (char*)str1;char* s1, * s2;if (!*str2)return((char*)str1);while (*cp){s1 cp;s2 (char*)str2;while (*s1 *s2 !(*s1 - *s2))s1, s2;if (!*s2)return(cp);cp;}return(NULL);
} 2.5 模拟实现strcmp int my_strcmp(const char* src, const char* dst)
{int ret 0;assert(src ! NULL);assert(dest ! NULL);while (!(ret *(unsigned char*)src - *(unsigned char*)dst) *dst)src, dst;if (ret 0)ret -1;else if (ret 0)ret 1;return(ret);
} 2.6 模拟实现memcpy void* memcpy(void* dst, const void* src, size_t count)
{void* ret dst;assert(dst);assert(src);/**copy from lower addresses to higher addresses*/while (count--) {*(char*)dst *(char*)src;dst (char*)dst 1;src (char*)src 1;}return(ret);
} 2.7 模拟实现memmove void* memmove(void* dst, const void* src, size_t count)
{void* ret dst;if (dst src || (char*)dst ((char*)src count)) {/** Non-Overlapping Buffers* copy from lower addresses to higher addresses*/while (count--) {*(char*)dst *(char*)src;dst (char*)dst 1;src (char*)src 1;}}else {/** Overlapping Buffers* copy from higher addresses to lower addresses*/dst (char*)dst count - 1;src (char*)src count - 1;while (count--) {*(char*)dst *(char*)src;dst (char*)dst - 1;src (char*)src - 1;}}return(ret);
}