- 一:字符的定义方式及输出
- 二:字符串在内存中的存储方式
- 三:strlen来计算字符串中字符个数
- 四:字符串操作常用函数
- 1.printf和puts函数都是输出字符串,scanf和get函数都是输入字符串,以及初始化函数memset的使用
- 2.拷贝函数strcpy和strncpy,拼接strcat和比较strcmp
- 3.查找子字符strchr和查子串strstr,转为小写的函数strlwr和转为大写的函数strupr
- 4.字符串分割strtok
- 五:自己实现字符串api
- 1.通过函数来自己实现字符串的api,puts输出和puts输入函数:
- 2.自己实现计算长度strlen和初始化memset
- 3.自己实现字符串拷贝strcpy和strncpy,
- 4.自己实现字符串的拼接strcat
1.什么是字符串?
字符串就是字符数组,好多个字符串起来的一组数据
2.直接看代码,注意自己写的注释
#includeint main() { int i; char c = 'c';//定义了一个字符数据类型c //所以,第一种定义字符串数组的方式 char str[3] = {'a','b','c'};//和整型数组相似 //访问方式 for(i-0;i printf("%c ",str[i]); } putchar('n'); //第二种定义字符按串数组的方式 char str2[3] = "abc";//也和整型数组相似 for(i=0;i printf("%c ",str2[i]); } putchar('n'); //第三种定义字符串的方式 char str3[] = "abc";//数组元素个数不写,会根据真实大小来默认分配 for(i=0;i printf("%c ",str3[i]); } putchar('n'); //第四种定义字符串数组的方式 char *pstr = "i am handsome";//指针方式,如果操作不恰当,内存非法,易造成段错误 printf("%s",pstr);//字符串用格式占位符%s表示,不需要用i的下标遍历 putchar('n'); return 0; }
3.运行结果:
1.下面用代码类比
#includeint main() { int a[3] = {1,2,3};//连续的空间,整个数组的大小是:元素的个数*元素类型的大小 printf("a数组的大小是:%ldn",sizeof(a)); printf("数组元素的大小是:%ldn",sizeof(a[0])); printf("数组元素大小是:%ldn",sizeof(int)); printf("数组的个数可以这么算:%ldn",sizeof(a)/sizeof(a[0])); puchar('n'); char a2[3] = {'a','b','c'}; printf("a2数组的大小是:%ldn",sizeof(a2)); printf("数组元素的大小是:%ldn",sizeof(a2[0])); printf("数组元素大小是:%ldn",sizeof(char)); printf("数组的个数可以这么算:%ldn",sizeof(a2)/sizeof(a2[0])); puchar('n'); char a3[3] = "abc"; printf("a3数组的大小是:%ldn",sizeof(a3)); printf("数组元素的大小是:%ldn",sizeof(a3[0])); printf("数组元素大小是:%ldn",sizeof(char)); printf("数组的个数可以这么算:%ldn",sizeof(a3)/sizeof(a3[0])); puchar('n'); //中括号不写数组的大小,上面说了会根据初始化的时候元素个数来确定 char a4[] = "abc"; printf("a4数组的大小是:%ldn",sizeof(a4)); printf("数组元素的大小是:%ldn",sizeof(a4[0])); printf("数组元素大小是:%ldn",sizeof(char)); printf("数组的个数可以这么算:%ldn",sizeof(a4)/sizeof(a4[0])); return 0; }
2.看运行结果:
3.注意看a4数组的大小,为什么是4而不是3?
三:strlen来计算字符串中字符个数是因为字符串在内存中,除了有效字符abc以外,还会自动在后面补上一个 ‘ ’ ,作为字符串的结束标志
四:字符串操作常用函数 1.printf和puts函数都是输出字符串,scanf和get函数都是输入字符串,以及初始化函数memset的使用不能用sizeof来计算字符串中有效字符的个数!!!应该要用strlen,它在计算字符串大小的时候,遇到 ‘ ’ 后,就结束计数!
#include#include #include int main() { char *str = "i am handsome"; printf("%s ",str); putchar('n'); puts(str); putchar('n'); //野指针,造成非法内存,出现段错误 char *pstr; pstr = (char *)malloc(128);//1.申请了空间 memset(pstr,' ',128);//2.初始化,把每个元素都初始化为' ' if(pstr == NULL){ printf("开辟空间失败!n"); exit(-1); } //对应的参数:1.初始化的对象 2.初始化成什么字符 3.初始化的大小 printf("请输入字符串:n"); //scanf("%s",pstr); gets(pstr); puts(pstr); return 0; }
2.看运行结果:
3.注意:
2.拷贝函数strcpy和strncpy,拼接strcat和比较strcmpa.一旦用malloc申请了空间,一定要注意内存泄漏的问题
b.malloc可能会开辟失败,要对返回值做判断
1.看代码
#include#include #include int main() { //拷贝原型:char *strcpy(char *dest, const char *src); char *strDest; strDest = (char *)malloc(128); memset(strDest,' ',128); char *strSrc = "iam handsome"; strcpy(strDest,strSrc); puts(strDest); putchar('n'); //拷贝原型:char *strncpy(char *dest, const char *src, size_t n); memset(strDest,' ',128); strncpy(strDest,strSrc,3);//相比strcpy多了一个拷贝长度的参数 puts(strDest); putchar('n'); // 拼接原型:char *strcat(char *dest, const char *src); char text[128] = "yes"; strcat(text,strSrc); puts(text); putchar('n'); //比较原型:int strcmp(const char *s1, const char *s2); char *str1 = "123"; char *str2 = "1234"; int ret = strcmp(str1,str2); printf("%dn",ret); return 0; }
2.看运行结果:
3.查找子字符strchr和查子串strstr,转为小写的函数strlwr和转为大写的函数strupr注意:比较strcmp,他返回的是一个整数,如果第一个参数大于第二个参数,那么返回的就是正数,反之返回的是负数。诺两个比较的参数相等,则返回的是0
1.看代码:
#include#include #include int main() { //查找子字符原型:char *strchr(const char *s, int c); char *str = "iamhandsome"; char c = 'h'; char *p = NULL; p = strchr(str,c); if(p == NULL){ printf("没找到!n"); }else{ printf("找到了!n"); puts(p); } putchar('n'); //查找子串原型:char *strstr(const char *haystack, const char *needle); char *substr = "am"; p = strstr(str,substr); if(p == NULL){ printf("没找到!n"); }else{ printf("找到了!n"); puts(p); } putchar('n'); // 转为小写的函数原型:char *strlwr(char *str) char *str1 = "I am Handsome"; puts(strlwr(str1)); puts(strupr(str1)); return 0; }
2.看运行结果:
#include#include #include int main() { //原型:char *strtok(char *str, const char *delim); char str[] = "i,am,hand,some"; char *psubs[10]; int i = 1; char *p = NULL; p = strtok(str,",");//第一次分割,返回的是第一次找到逗号前面的字符串! if(p != NULL){ psubs[i-1] = p; } while(1){ i++; p = strtok(NULL,",");//第二次分割,必须还得使用该函数,注意第一个参数为NULL if(p != NULL){ psubs[i-1] = p; }else{ printf("没有子串了!n"); break; } } int j; for(j=0;j puts(psubs[j]); } system("pause"); return 0; }
运行结果:
#include#include #include void myputs(char *p)//自己实现输出api { while(*p != ' '){ putchar(*p++); } putchar('n'); } void mygets(char *p)//自己实现输入api { if(p == NULL){ printf("内存非法!n"); return; } while(*p = getchar()){ if(*p == 'n'){ return; }else{ p++; } } } int main() { char str[128] = {' '}; char *p = "i am handsome"; myputs(p); myputs("请输入你的字符串"); mygets(str); myputs(str); return 0; }
2.看运行结果:
1.看代码:
#include#include #include int mystrlen(char *p) { int cnt = 0; while(*p++ != ' '){ cnt++; } return cnt; } void mymemset(char *p,char c,int size) { while(size){ *p++ = c; size--; } } int main() { char *str = "i am handsome"; printf("字符串长度是:%dn",mystrlen(str)); char *str2 = NULL; str2 = (char *)malloc(6); mymemset(str2,'v',6); str2[6] = ' '; puts(str2); }
2.运行结果:
1:代码
#include#include #include char *mystrcpy(char *dest, const char *src) { if(dest == NULL || src == NULL){ return NULL; } while(*src != ' '){ *dest++ = *src++; } *dest = ' '; return dest; } char *mystrncpy(char *dest, const char *src,int n) { if(dest == NULL || src == NULL){ return NULL; } while(*src != ' ' && n>0){ *dest++ = *src++; n--; } *dest = ' '; return dest; } int main() { char *str = "i am handsome"; char *dest; dest = (char *)malloc(128); memset(dest,' ',128); mystrcpy(dest,str); puts(dest); mystrncpy(dest,str,2); puts(dest); return 0; }
2.运行结果:
#include#include #include void mystrcat(char *dest,char *src) { while(*dest != ' '){ dest++; } while(*src != ' '){ *dest++ = *src++; } *dest = ' '; } int main() { char dest[128] = "yes "; char *src = "i am handsome"; mystrcat(dest,src); puts(dest); system("pause"); return 0; }
看运行结果: