初识字符串
逻辑跟整型差不多
char cdata[] = "hello world !";
for(int i = 0;i < sizeof(cdata)/sizeof(cdata[0]);i ++){
printf("%c",cdata[i]);
}
//或者puts(cdata);
return 0;
或者
char* pchar = "hello world !";
for(int i = 0;i < 13;i ++){
printf("%c",*(pchar+i));
}
return 0;
当然,依然不够简洁
char* pchar = "hello world !";
printf("%s",pchar);
return 0;
或者直接
char* pchar = "hello world !";
puts(pchar);
char cdata[]和char* pchar是有区别的,char cdata[]是一个变量,可以修改,但char* pchar是一个常量,不能被修改
字符串的内存方式及结束标志
int data[] = {1,2,3,4,5};
char cdata[] = "hello";
int len = sizeof(data)/sizeof(data[0]);
printf("intlen = %d\n",len);
len = sizeof(cdata)/sizeof(cdata[0]);
printf("charlen = %d\n",len);
结果
在内存中字符串的结束标志是'\0'如果没写,会自动加上
sizeof和strlen的区别
char cdata[] = "hello";
char cdata2[128] = "hello";
printf("sizeof :%d\n",sizeof(cdata));
printf("strlen :%d\n",strlen(cdata));
printf("sizeof2 :%d\n",sizeof(cdata2));
printf("strlen2 :%d\n",strlen(cdata2));
char* p = "hellooo";
printf("sizeofp :%d\n",sizeof(p));
printf("strlenp :%d\n",strlen(p));
sizeof:内存占用大小,单位字节,指针占用8个字节,函数和字符型占用一个字节
strlen:返回有效字符的个数,,而且需要调用<string.h>
malloc动态开辟内存空间
函数原型:void *malloc(size_t size)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char* p;//野指针,没有指向固定的地址
p = (char*)malloc(1);//p有了内存指向
*p = 'c';
free(p);
p = (char*)malloc(12);
stpcpy(p,"gyufyt");
puts(p);
return 0;
}
free:释放内存空间,防止悬挂指针(野指针的一种)
如果strcpy内容大于开辟的空间,会越界,导致程序崩溃
p = (char*)malloc(12);
stpcpy(p,"gyufytfytftgyuguyguyguyyuf");
puts(p);
此时需要扩容
realloc:void *realloc(void *ptr,size_t size)
清理空间:
memset(void *ptr,int c,size_t size)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char* p;//野指针,没有指向固定的地址
p = (char*)malloc(1);//p有了内存指向
*p = 'c';
free(p);
p = NULL;
p = (char*)malloc(12);
if(p==NULL){
printf("malloc error");
exit(-1);
}
memset(p,'\0',12);
printf("扩容前地址:%x\n",p);
int len = strlen("gyufytfytftgyuguyguyguyyuf");
int newlen = len - 12 + 1;
realloc(p,newlen);
printf("扩容后地址:%x\n",p);
stpcpy(p,"gyufytfytftgyuguyguyguyyuf");
puts(p);
return 0;
}
常用API
输出字符串
puts(p)
printf("%s",p)
获取字符串
gets
因为本函数可以无限读取,易发生溢出。如果溢出,多出来的字符将被写入堆栈中,就覆盖了原先的内容,破坏一个或多个不相关的变量的值
char str[128] = {'\0'};
puts("请输入字符串");
//scanf("%s",str);
gets(str);
puts(str);
自己实现复制函数
#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++ = * src++;
}
*/
while((* des++ = * src++) != '\0');
*des = '\0';
return bak;
}
char* myStrncpy(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 = "how are you?";
myStrcpy(str,p);
puts(str);
myStrncpy(str,p,6);
puts(str);
return 0;
}
assert断言函数
相当于if函数
例如以上代码中的myStrcpy可写为
#include <assert.h>
char* myStrcpy(char* des,char* src)
{
assert(des != NULL && src != NULL)
char* bak = des;
while((* des++ = * src++) != '\0');
*des = '\0';
return bak;
}
如果值为假,他会像stderr打印一条出错信息,缺点是消耗内存较大
字符串拼接strcat
#include <stdio.h>
#include <string.h>
int main()
{
char str[128] = "andy";
char* p = " is handsome";
strcat(str,p);
puts(str);
return 0;
}
自写
#include <stdio.h>
#include <assert.h>
char* myStrcat(char* des,char* src)
{
char* bak = des;
assert(des != NULL && src != NULL);
while(*des != '\0'){
des ++;
}
while((*des ++ = *src++) != '\0');
*des = '\0';
return bak;
}
int main()
{
char str[128] = "andy";
char* p = " is handsome";
myStrcat(str,p);
puts(str);
return 0;
}
其他写法
char* myStrcat2(char* des,char* src)
{
char* bak = des;
strcpy(des+strlen(des),src);
return bak;
}
char* myStrcat3(char* des,char* src)
{
char* bak = des;
assert(des != NULL && src != NULL);
for(;*des != '\0';des++);
while((*des ++ = *src++) != '\0');
*des = '\0';
return bak;
}
字符串比较strcmp
strcmp: int strcmp(const char* s1,const char* s2);若s1=s2,则返回0;若s1<s2返回负数,反之正数
strncmp: int strncmp(const char* s1,const char* s2,size_t n);比较s1和s2,最多比较前n个字节,若前n个字节相同,则返回0;若s1<s2返回负数,反之正数
#include <stdio.h>
#include <string.h>
#include <string.h>
int main()
{
char* p1 = "andya";
char* p2 = "andyc";
int ret = strcmp(p1,p2);
printf("ret = %d\n",ret);
return 0;
}
函数实现
#include <stdio.h>
#include <string.h>
#include <string.h>
int myStrcmp(char* str1,char* str2)
{
int ret = 0;
int n_str1 = 0;
int n_str2 = 0;
char* bakStr1 = str1;
char* bakStr2 = str2;
while(* str1 && * str2 && (*str1==*str2)){
str1++;
str2++;
}
if(*str1 || *str2){
str1 = bakStr1;
str2 = bakStr2;
while(*str1){
n_str1 += *str1;
str1 ++;
}
while(*str2){
n_str2 += *str2;
str2 ++;
}
}
ret = n_str1 - n_str2;//比较SCII码总和
if(ret < 0){
ret = -1;
}
if(ret > 0){
ret = 1;
}
return ret;
}
int main()
{
char* p1 = "andyfg";
char* p2 = "andysl";
int ret = myStrcmp(p1,p2);
printf("myret = %d\n",ret);
return 0;
}