第七章 字符串
定义
字符串就是字符数组
如何定义
#include<stdio.h>
int main()
{
char cdata[]={'h','e','l','l','o'};
char cdata2[]="hello";
char *pchar="hello";
int i;
printf("%s",pchar);
putchar('\n');
puts(pchar);
for(i=0;i<5;i++)
{
//printf("%c",cdata[i]);
//printf("%c",cdata2[i]);
printf("%c",*(pchar+i));
}
return 0;
}
- 和整型一样
- 和整型数组一个道理——char str[]={'h','e','l','l','o'}
- 改进——char str[]="hello"
- 一般用 char *p="hello"
3和4的区别——3是字符串变量,4是字符串常量(不可以被修改)
字符串和字符数组的区别
字符串的结束标志是\0
char cdata[6]={'h','e','l','l','o','\0'}应该在字符数组后面加上\0
sizeof和strlen的区别
sizeof是所有的大小,strlen是有效字符的大小
#include<stdio.h>
#include<string.h>
int main()
{
char cdata[]="hello";//\0
printf("sizeof:%d\n",sizeof(cdata));
printf("strlen:%d\n",strlen(cdata));
char *p="hello";
//p是一个char *,sizeof来计算的时候,得出的是计算机用多少字节来表示一个地址
printf("sizeof:%d\n",sizeof(p));
printf("strlen:%d\n",strlen(p));
return 0;
}
动态开辟字符串
malloc函数——函数原型void *malloc(size_t size(内存大小))——c库函void *malloc(size_t size)分配所需的内存空间,并返回一个指向它的指针
realloc函数——函数原型void *relloc(void *ptr(需要扩容的地址),size_t size(新增内存大小)) ——扩容——c库函数void *relloc(void *ptr,size_t size)尝试重新调整之前调用malloc或calloc所分配分配的ptr所指向的内存块的大小
free函数——c库函数void free(void *ptr)释放之前调用malloc,calloc或者realloc所分配的内存空间——防止内存泄漏,防止悬挂指针(野指针的一种)
memset函数——函数原型 void *memset(void*str,int c ,size_t n)
字符串常用API
输出字符串
获取字符串
scanf("%s",cdata)
gets——char *gets(char *str)
复制字符串
strcpy——char* strcpy(char* destination(目标),const char* source);
参数说明
char* destination---------目标字符串的首地址
const char* source------源地址:被复制的字符串的首地址,用const修饰,避免修改掉被拷贝的字符串
返回的是目标字符串的首地址
使用strcpy的注意事项
- 源字符必须以 '\0'结束——char arr2[] = { 'a','b','c','d' };类似于数组的字符串不可以
- 要注意备份原来的地址来保存src中的字符串
- 目标空间必须足够大,以确保能放源字符串
- 目标空间必须可变——char* str1="hello"常量字符串不可以更改
strncpy——char *strncpy(char *dest, const char *src, int n)
参数说明
dest 目标字符串
src 源字符串
n 要拷贝的源字符串的个数
tips
说明:
1、当src字符串长度小于n时,则拷贝完字符串后,剩余部分将用空字节填充,直到n个
strncpy不会向dest追加’\0’。
2、src和dest所指的内存区域不能重叠,且dest必须有足够的空间放置n个字符
返回值:dest字符串起始地址
代码展示
#include<stdio.h>
char* mystrcpy(char *des,char *src)
{
if(des==NULL||src==NULL)
{
return NULL;
}
char *bak=des;//创建备份
while(*src!='\0')
{
*des=*src;
des++;
src++;
}
*des='\0';
return bak;
}
char* mystrcpy2(char *des,char *src)
{
if(des==NULL||src==NULL)
{
return NULL;
}
char *bak=des;//创建备份
while(*src!='\0')
{
*des++=*src++;
}
*des='\0';
return bak;
}
char* mystrcpy(char *des,char *src)
{
if(des==NULL||src==NULL)
{
return NULL;
}
char *bak=des;//创建备份
while((*des++=*src++)='\0');
*des='\0';
return bak;
}
char* mystrncpy2(char *des,char *src,int count)
{
if(des==NULL||src==NULL)
{
return NULL;
}
char *bak=des;//创建备份
while(*src!='\0'&&count>0)
{
*des++=*src++;
count--;
}
if (count >0)
{
while(count >0)
{
count--:
*des='\0';
}
return des;
}
*des='\0';
return bak;
}
int main()
{
char str[128]={'\0'};
char *p="huangwenqi handsome";
mystrcpy(str,p);
puts(str);
return 0;
}
断言
assert
拼接
strcat——char *strcat(char*dest,const char*str)——把src所指向的字符串复制到dest所指向的字符串的后面(删除*dest原来末尾的\0)要保证*dest足够长,以容纳被复制进来的*src。*src中原有的字符不变。返回指向dest的指针